2009-07-27 42 views
3

我很迷惑minidom解析器处理空元素,如下面的代码部分所示。Python中的空XML元素处理

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> 

我该如何获得一致的行为?我想收到空字符串作为值空元素(其中IS我放在XML结构中的第一位)。

回答

4

破解开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方法,以便在没有包含非空文本内容的子节点时打印出短标签表单。然后monkeypatch模块以使用您的新Element元素。

1
value = thing.firstChild.nodeValue or '' 
+0

不幸的是,这并没有解决我的问题。在我的代码中,我在XML文档中的TextElement上调用方法replaceWholeText。如果我以前在该TextElement中存储了空字符串,它将在下一次解析XML文件时消失,并且我将无法调用方法replaceWholeText。如果它不在那里,我可以重建那个元素,但这将是一个非常丑陋的黑客。 – Josip 2009-07-27 14:47:03

+0

你是什么意思“重建元素”?它的存在,它的价值恰好是None而不是''。 – 2009-07-27 15:22:14

1

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