2009-06-14 6 views
11

Quiero agregar doctypes a mis documentos XML que estoy generando con el etree de LXML.Creando un doctype con el etree de lxml

Sin embargo, no puedo entender cómo agregar un tipo de documento. Hardcoding y concating the string no es una opción.

que estaba esperando algo a lo largo de las líneas de la forma de PI se añaden en etree:

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

Pero no funciona para mí. ¿Cómo agregar un documento a xml con lxml?

Respuesta

8

Puede crear el documento con un tipo de documento, para empezar:

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

impresiones:

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

Si desea añadir un tipo de documento XML a algunos que no fue creada con uno, primero puede crear una con el tipo de documento que desee (como el anterior), y luego copiar el código XML DOCTYPE-menos en él:

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

grabados:

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

¿Eso es lo que está buscando?

+0

El enlace está desactualizado. –

4

El PI se ha agregado realmente como un elemento anterior de "doc". Por lo tanto, no es un hijo de "doc". Debe utilizar "doc.getroottree()"

Aquí se muestra un ejemplo:

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

Esta debería ser la respuesta correcta. – Tom

26

Esto funcionó para mí:

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

+0

Solución mucho más limpia para un árbol ya existente. Gracias. – Khorkrak

Cuestiones relacionadas