2009-06-14 9 views
11

Desidero aggiungere doctypes ai miei documenti XML che sto generando con l'etree di LXML.Creazione di un doctype con etx lxml

Tuttavia non riesco a capire come aggiungere un doctype. Hardcoding e concatenare la stringa non è un'opzione.

mi aspettavo qualcosa sulla falsariga di quanto PI di sono aggiunti in eTree:

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

Ma non funziona per me. Come aggiungere un documento XML a lxml?

risposta

8

È possibile creare il documento con un doctype per cominciare:

# 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") 

stampe:

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

Se si desidera aggiungere un doctype a qualche XML che non è stato creato con uno, puoi prima crearne uno con il doctype desiderato (come sopra), quindi copiare il tuo XML senza documet in quanto:

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

stampe:

<?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> 

È quello che stai cercando?

+0

Il collegamento non è aggiornato. –

4

Il PI viene effettivamente aggiunto come elemento precedente da "doc". Quindi, non è un figlio di "doc". È necessario utilizzare "doc.getroottree()"

Ecco un esempio:

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

con 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

Questa dovrebbe essere la risposta corretta. – Tom

26

Questo ha funzionato per me:

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

+0

Soluzione molto più pulita per un albero già esistente. Grazie. – Khorkrak