Python中的空XML元素处理

Python中的空XML元素处理,python,xml,string,Python,Xml,String,我对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.

我对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>
import xml.dom.minidom
doc=xml.dom.minidom.parseString(“”)
打印doc.firstChild.nodeValue.\uuu repr\uuu()
#出局:无
打印doc.firstChild.toxml()文件
#输出:
doc=xml.dom.minidom.Document()
v=doc.appendChild(doc.createElement('value'))
v、 appendChild(doc.createTextNode(“”))
打印v.firstChild.nodeValue.\uu repr\uuu()
#输出:“”
打印doc.firstChild.toxml()文件
#输出:

我如何才能获得一致的行为?我希望接收空字符串作为空元素的值(这是我首先在XML结构中输入的内容)。

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

打开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))
元素(节点)类的方法。 def writexml(self、writer、indent=“”、addendent=“”、newl=“”): #[剪报] 如果self.childNodes: writer.write(“>%s”%(newl)) 对于self.childNodes中的节点: writexml(writer,indent+addindent,addindent,newl) writer.write(“%s%s”%(缩进,self.tagName,newl)) 其他: 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>'
>doc=Document()
>>>v=doc.appendChild(doc.createElement('v'))
>>>v.toxml()
''
>>>v.childNodes
[]
>>>v.appendChild(doc.createTextNode(“”))
>>>v.childNodes
[]
>>>v.toxml()
''
正如Lloyd所指出的,XML规范对两者没有区别。如果您的代码确实做出了区分,这意味着您需要重新考虑如何序列化数据


minidom只是显示一些不同的内容,因为它更容易编码。但是,您可以获得一致的输出。只需继承
元素
类并重写
toxml
方法,这样当没有包含非空文本内容的子节点时,它将打印出短端标记表单。然后monkeypatch命令模块使用新元素类。

不幸的是,这并不能解决我的问题。在我的代码中,我在XML文档中的TextElement上调用方法replaceWholeText。若我以前在那个TextElement中存储了空字符串,那个么下次解析XML文件时它就会消失,并且我将无法调用方法replaceWholeText。我可以重建元素,如果它不在那里,但那将是一个非常丑陋的黑客行为。你说的“重建元素”是什么意思?它存在,它的值正好是None而不是“”。这正是我的观点。XML规范将两种形式定义为等效形式,但如果在运行时创建,minidom将被视为“”,但在没有TextElemet子节点的情况下解析为元素“v”。我按照您的建议更改了数据序列化方法。我将尝试JSON,因为它更适合我的需要。谢谢你的帮助。
>>> 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>'