我对 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>
如何获得一致的行为?我想接收空字符串作为空元素的值(这是我首先放入 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))
由此我们可以推断,short-end-tag 形式仅在 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
方法,当没有非空文本内容的子节点时,打印出short-end-tag形式。然后对模块进行 monkeypatch 以使用您的新 Element 类。
关于python - Python 中的空 XML 元素处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1187718/