Пустая обработка элементов XML в Python

Я озадачен обработкой парсингами 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>' 

Как отметил Ллойд, спецификация XML не делает различий между ними. Если ваш код делает различие, это означает, что вам нужно переосмыслить, как вы хотите сериализовать свои данные.

xml.dom.minidom просто отображает что-то по-другому, потому что его легче кодировать. Однако вы можете получить согласованный вывод. Просто наследуйте класс Element и переопределите метод toxml , чтобы он распечатывал форму short-end-tag, когда нет дочерних узлов с непустым текстовым контентом. Затем monkeypatch модуль, чтобы использовать ваш новый класс Element.

 value = thing.firstChild.nodeValue or '' 

Спецификация Xml не отличает эти два случая.