2009-07-27 75 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規範不區分這兩種情況。