【问题标题】:Empty XML element handling in PythonPython 中的空 XML 元素处理
【发布时间】:2009-07-27 11:46:32
【问题描述】:

我对 minidom 解析器对空元素的处理感到困惑,如下代码部分所示。

import xml.dom.minidom

doc = xml.dom.minidom.parseString('<value></value>')
print doc.firstChild.nodeValue.__repr__()
# Out: None
print doc.firstChild.toxml()
# Out: <value/>

doc = xml.dom.minidom.Document()
v = doc.appendChild(doc.createElement('value'))
v.appendChild(doc.createTextNode(''))
print v.firstChild.nodeValue.__repr__()
# Out: ''
print doc.firstChild.toxml()
# Out: <value></value>

如何获得一致的行为?我想接收 empty string 作为 empty element 的值(这 IS 我首先放在 XML 结构中)。

【问题讨论】:

    标签: python xml string


    【解决方案1】:

    破解打开 xml.dom.minidom 并搜索“/>”,我们发现:

    # Method of the Element(Node) class.
    def writexml(self, writer, indent="", addindent="", newl=""):
        # [snip]
        if self.childNodes:
            writer.write(">%s"%(newl))
            for node in self.childNodes:
                node.writexml(writer,indent+addindent,addindent,newl)
            writer.write("%s</%s>%s" % (indent,self.tagName,newl))
        else:
            writer.write("/>%s"%(newl))
    

    我们可以由此推断,短尾标签形式仅在 childNodes 为空列表时出现。确实,这似乎是真的:

    >>> doc = Document()
    >>> v = doc.appendChild(doc.createElement('v'))
    >>> v.toxml()
    '<v/>'
    >>> v.childNodes
    []
    >>> v.appendChild(doc.createTextNode(''))
    <DOM Text node "''">
    >>> v.childNodes
    [<DOM Text node "''">]
    >>> v.toxml()
    '<v></v>'
    

    正如 Lloyd 所指出的,XML 规范对两者没有区别。如果您的代码确实做出了区分,这意味着您需要重新考虑如何序列化您的数据。

    xml.dom.minidom 只是显示不同的东西,因为它更容易编码。但是,您可以获得一致的输出。只需继承Element 类并重写toxml 方法,这样它就会在没有包含非空文本内容的子节点时打印出短尾标签表单。然后对模块进行猴子补丁以使用新的 Element 类。

    【讨论】:

    • 这正是我的观点。 XML 规范将两种形式定义为等效的,但如果在运行时创建,minidom 将 视为 '',但将 解析为没有 TextElemet 子节点的元素“v”。
    • 我听从了您的建议,改变了我对数据序列化的方法。我会尝试 JSON,因为它更适合我的需求。感谢您的帮助。
    【解决方案2】:
    value = thing.firstChild.nodeValue or ''
    

    【讨论】:

    • 不幸的是,这并不能解决我的问题。在我的代码中,我在 XML 文档中的 TextElement 上调用方法 replaceWholeText。如果我之前在该 TextElement 中存储了空字符串,那么下次解析 XML 文件时它会消失,并且我将无法调用方法 replaceWholeText。如果它不存在,我可以重建该元素,但那将是一个非常丑陋的 hack。
    • “重建元素”是什么意思?它存在,它的值恰好是 None 而不是 ''。
    【解决方案3】:

    Xml 规范不区分这两种情况。

    【讨论】:

      猜你喜欢
      • 2017-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多