2009-05-14 7 views
24

Je suis en train de générer un document XML avec des espaces de noms, actuellement avec le xml.dom.minidom Python:Comment générer des documents XML avec espaces de noms dans Python

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

L'espace de noms est enregistré (doc.childNodes[0].namespaceURI est 'http://example.net/ns'), mais pourquoi est-ce qu'il manque dans la sortie?

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

Je me attends:

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

ou

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

Répondre

5

Cette fonctionnalité est déjà proposée; un patch est slumbering in the Python bug database. Voir la réponse de Tomalak (en bref: ajouter manuellement l'attribut xmlns) pour une solution de contournement.

21

createElementNS() est défini comme:

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()) 

rendements:

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

... pas tout à fait ...

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()) 

Rendement:

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

alternative:

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 produit:

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

Il semble que vous auriez à le faire manuellement. Element.writexml() ne montre aucune indication que les espaces de noms obtiendraient un traitement spécial.

EDIT: Cette réponse est destinée à xml.dom.minidom uniquement, puisque l'OP l'a utilisé dans la question. Je n'indique pas qu'il était impossible d'utiliser des espaces de noms XML en Python en général. ;-)

+0

Cela fonctionne, mais c'est un bidouillage. Je ne me souviens pas d'une autre implémentation DOM prenant en compte les espaces de noms qui ne supporte pas vraiment les espaces de noms. J'espère qu'il y en a un pour Python aussi. – phihag

+0

Je cherchais le code source pour minidom, et il semble que ce hack soit le plus proche possible. Le support "output" pour les espaces de noms dans minidom est quasiment inexistant (AFAICS), ils ne reçoivent aucun traitement particulier. Cependant, ils sont analysés correctement, donc quand ils étaient dans la chaîne d'entrée, ils seront aussi dans la sortie. A part ça, minidom les traite comme des attributs normaux et des éléments avec des noms amusants. – Tomalak

Questions connexes