2009-06-14 9 views
11

Je souhaite ajouter des types de documents à mes documents XML que je génère avec etree de LXML.Création d'un doctype avec lxml etree

Cependant je ne peux pas comprendre comment ajouter un doctype. Le codage en dur et la concaténation de la chaîne ne sont pas une option.

j'attendais quelque chose le long des lignes de la façon dont PI sont ajoutés à ce etree:

pi = etree.PI(...) 
doc.addprevious(pi) 

Mais il ne fonctionne pas pour moi. Comment ajouter un à un document XML avec lxml?

Répondre

8

Vous pouvez créer votre document avec un doctype pour commencer:

# Adapted from example on http://codespeak.net/lxml/tutorial.html 
import lxml.etree as et 
import StringIO 
s = """<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE root SYSTEM "test" [ <!ENTITY tasty "cheese"> 
<!ENTITY eacute "&#233;"> ]> 
<root> 
<a>&tasty; souffl&eacute;</a> 
</root> 
""" 
tree = et.parse(StringIO.StringIO(s)) 
print et.tostring(tree, xml_declaration=True, encoding="utf-8") 

impressions:

<?xml version='1.0' encoding='utf-8'?> 
<!DOCTYPE root SYSTEM "test" [ 
<!ENTITY tasty "cheese"> 
<!ENTITY eacute "&#233;"> 
]> 
<root> 
<a>cheese soufflé</a> 
</root> 

Si vous souhaitez ajouter un type de document XML à certains qui n'a pas été créé avec un, vous pouvez en créer un avec le type de document désiré (comme ci-dessus), puis y copier votre code XML sans doctype:

xml = et.XML("<root><test/><a>whatever</a><end_test/></root>") 
root = tree.getroot() 
root[:] = xml 
root.text, root.tail = xml.text, xml.tail 
print et.tostring(tree, xml_declaration=True, encoding="utf-8") 

estampes:

<?xml version='1.0' encoding='utf-8'?> 
<!DOCTYPE root SYSTEM "test" [ 
<!ENTITY tasty "cheese"> 
<!ENTITY eacute "&#233;"> 
]> 
<root><test/><a>whatever</a><end_test/></root> 

Est-ce ce que vous cherchez?

+0

Le lien est désuet. –

4

Le PI est ajouté en tant qu'élément précédent à partir de "doc". Ainsi, ce n'est pas un enfant de "doc". Vous devez utiliser "doc.getroottree()"

Voici un exemple:

>>> root = etree.Element("root") 
>>> a = etree.SubElement(root, "a") 
>>> b = etree.SubElement(root, "b") 
>>> root.addprevious(etree.PI('xml-stylesheet', 'type="text/xsl" href="my.xsl"')) 
>>> print etree.tostring(root, pretty_print=True, xml_declaration=True, encoding='utf-8') 
<?xml version='1.0' encoding='utf-8'?> 
<root> 
    <a/> 
    <b/> 
</root> 

avec getroottree():

>>> print etree.tostring(root.getroottree(), pretty_print=True, xml_declaration=True, encoding='utf-8') 
<?xml version='1.0' encoding='utf-8'?> 
<?xml-stylesheet type="text/xsl" href="my.xsl"?> 
<root> 
    <a/> 
    <b/> 
</root> 
+0

Cela devrait être la bonne réponse. – Tom

26

Cela a fonctionné pour moi:

print etree.tostring(tree, pretty_print=True, xml_declaration=True, encoding="UTF-8", doctype="<!DOCTYPE TEST_FILE>")

+0

Solution beaucoup plus propre pour un arbre déjà existant. Merci. – Khorkrak

Questions connexes