2009-06-14 2 views
11

Я хочу добавить doctypes к своим XML-документам, которые я генерирую с помощью etree LXML.Создание doctype с lxml's etree

Однако я не могу понять, как добавить doctype. Жесткое кодирование и согласование строки не является опцией.

я ожидал что-то вдоль линий, как PI, будут добавлены в etree:

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

Но это не работает для меня. Как добавить в xml-документ с помощью lxml?

ответ

8

Вы можете создать документ с DOCTYPE, чтобы начать с:

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

принтами:

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

Если вы хотите добавить доктайп к некоторому XML, который не был создан с одной, вы можете сначала создать один из них с требуемым типом doctype (как указано выше), а затем скопировать в него свой XML-документ без содержания:

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

отпечатки:

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

Это вы что искали?

+0

Ссылка устарела. –

4

PI фактически добавлен как предыдущий элемент из «doc». Таким образом, это не ребенок «док». Вы должны использовать "doc.getroottree()"

Вот пример:

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

с 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

Это должен быть правильный ответ. – Tom

26

Это работает для меня:

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

+0

Многое лучшее решение для уже существующего дерева. Благодарю. – Khorkrak

Смежные вопросы