2009-05-14 4 views
24

Ich versuche, ein XML-Dokument mit Namespaces zu erzeugen, die derzeit mit Python xml.dom.minidom generieren:Wie XML-Dokumente mit Namespaces in Python

import xml.dom.minidom 
doc = xml.dom.minidom.Document() 
el = doc.createElementNS('http://example.net/ns', 'el') 
doc.appendChild(el) 
print(doc.toprettyxml()) 

Der Namespace gespeichert (doc.childNodes[0].namespaceURI ist 'http://example.net/ns'), aber warum fehlt es in der Ausgabe?

<?xml version="1.0" ?> 
<el/> 

erwarte ich:

<?xml version="1.0" ?> 
<el xmlns="http://example.net/ns" /> 

oder

<?xml version="1.0" ?> 
<randomid:el xmlns:randomid="http://example.net/ns" /> 

Antwort

21

createElementNS() ist definiert als:

def createElementNS(self, namespaceURI, qualifiedName): 
    prefix, localName = _nssplit(qualifiedName) 
    e = Element(qualifiedName, namespaceURI, prefix) 
    e.ownerDocument = self 
    return e 

so ...

import xml.dom.minidom 
doc = xml.dom.minidom.Document() 
el = doc.createElementNS('http://example.net/ns', 'ex:el') 
#--------------------------------------------------^^^^^ 
doc.appendChild(el) 
print(doc.toprettyxml()) 

ergibt:

<?xml version="1.0" ?> 
<ex:el/> 

... nicht ganz da ...

import xml.dom.minidom 
doc = xml.dom.minidom.Document() 
el = doc.createElementNS('http://example.net/ns', 'ex:el') 
el.setAttribute("xmlns:ex", "http://example.net/ns") 
doc.appendChild(el) 
print(doc.toprettyxml()) 

ergibt:

<?xml version="1.0" ?> 
<ex:el xmlns:ex="http://example.net/ns"/> 

alternativ:

import xml.dom.minidom 
doc = xml.dom.minidom.Document() 
el = doc.createElementNS('http://example.net/ns', 'el') 
el.setAttribute("xmlns", "http://example.net/ns") 
doc.appendChild(el) 
print(doc.toprettyxml()) 

wich produziert:

<?xml version="1.0" ?> 
<el xmlns="http://example.net/ns"/> 

Es sieht aus wie Sie es manuell zu tun haben würde. Element.writexml() zeigt keinen Hinweis darauf, dass Namespaces eine spezielle Behandlung erhalten würden.

EDIT: Diese Antwort ist nur auf xml.dom.minidom gerichtet, da das OP es in der Frage verwendet. Ich gebe nicht an, dass es unmöglich war, XML-Namespaces in Python generell zu verwenden. ;-)

+0

Das funktioniert, aber es ist ein ziemlicher Hack. Ich kann mich an keine andere namespace-fähige DOM-Implementierung erinnern, die Namespaces nicht wirklich unterstützt. Ich hoffe, dass es auch einen für Python gibt. – phihag

+0

Ich suchte nach dem Quellcode für Minidom, und es sieht so aus, als ob dieser Hack der nächste ist, den du bekommen kannst. Die "output" -Unterstützung für Namespaces in Minidom ist praktisch nicht existent (AFAICS), sie erhalten keine spezielle Behandlung. Sie werden jedoch korrekt analysiert. Wenn sie in der Eingabezeichenfolge waren, werden sie auch in der Ausgabe enthalten sein. Andere als das Minidom behandelt sie als normale Attribute und Elemente mit lustigen Namen. – Tomalak