2009-06-14 7 views
11

Ich möchte doctypes zu meinen XML-Dokumenten hinzufügen, die ich mit Etree LXML erzeuge.Erstellen eines Doctype mit lxml's etree

Allerdings kann ich nicht herausfinden, wie man einen Doctype hinzufügen. Hardcoding und Concrating der Zeichenfolge ist keine Option.

Ich hatte erwartet, etwas entlang der Linien, wie PI in etree hinzugefügt:

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

Aber es funktioniert nicht für mich. Wie füge ich zu einem XML-Dokument mit lxml hinzu?

Antwort

8

Sie Ihr Dokument mit einem Doctype erstellen beginnen:

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

druckt:

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

Wenn Sie einen Doctype einige XML hinzufügen möchten, die nicht mit einer erstellt wurde, Sie können zuerst eine mit dem gewünschten Doctype erstellen (wie oben), und dann Ihre Doctype-lose XML-Datei darin kopieren:

druckt:

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

Ist das wonach Sie suchen?

+0

Der Link ist veraltet. –

4

Der PI wird tatsächlich als vorheriges Element von "doc" hinzugefügt. Somit ist es kein Kind von "Doc". Sie müssen "doc.getroottree()"

verwenden Hier ist ein Beispiel:

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

mit 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

Dies sollte die richtige Antwort sein. – Tom

26

Das ist für mich gearbeitet:

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

+0

Viel sauberere Lösung für einen bereits bestehenden Baum. Vielen Dank. – Khorkrak