Передача спецификаций пространства имен с ElementTree в Python - PullRequest
27 голосов
/ 15 февраля 2011

Я пытаюсь создать файл XML с деревом элементов, который содержит декларацию XML и пространства имен. Вот мой пример кода:

from xml.etree import ElementTree as ET
ET.register_namespace('com',"http://www.company.com") #some name

# build a tree structure
root = ET.Element("STUFF")
body = ET.SubElement(root, "MORE_STUFF")
body.text = "STUFF EVERYWHERE!"

# wrap it in an ElementTree instance, and save as XML
tree = ET.ElementTree(root)

tree.write("page.xml",
           xml_declaration=True,
           method="xml" )

Однако ни тег <?xml не появляется, ни информация о пространстве имен / префиксах. Я здесь более чем запутался.

Ответы [ 2 ]

31 голосов
/ 15 февраля 2011

Хотя документы говорят иначе, я смог получить объявление <?xml> только указав xml_declaration и кодировку.

Вы должны объявить узлы в зарегистрированном вами пространстве имен, чтобы получить пространство имен для узлов в файле. Вот исправленная версия вашего кода:

from xml.etree import ElementTree as ET
ET.register_namespace('com',"http://www.company.com") #some name

# build a tree structure
root = ET.Element("{http://www.company.com}STUFF")
body = ET.SubElement(root, "{http://www.company.com}MORE_STUFF")
body.text = "STUFF EVERYWHERE!"

# wrap it in an ElementTree instance, and save as XML
tree = ET.ElementTree(root)

tree.write("page.xml",
           xml_declaration=True,encoding='utf-8',
           method="xml")

Вывод (page.xml)

<?xml version='1.0' encoding='utf-8'?><com:STUFF xmlns:com="http://www.company.com"><com:MORE_STUFF>STUFF EVERYWHERE!</com:MORE_STUFF></com:STUFF>

ElementTree также не печатает симпатично. Вот довольно печатный вывод:

<?xml version='1.0' encoding='utf-8'?>
<com:STUFF xmlns:com="http://www.company.com">
    <com:MORE_STUFF>STUFF EVERYWHERE!</com:MORE_STUFF>
</com:STUFF>

Вы также можете объявить пространство имен по умолчанию и не нужно его регистрировать:

from xml.etree import ElementTree as ET

# build a tree structure
root = ET.Element("{http://www.company.com}STUFF")
body = ET.SubElement(root, "{http://www.company.com}MORE_STUFF")
body.text = "STUFF EVERYWHERE!"

# wrap it in an ElementTree instance, and save as XML
tree = ET.ElementTree(root)

tree.write("page.xml",
           xml_declaration=True,encoding='utf-8',
           method="xml",default_namespace='http://www.company.com')

Вывод (интервал довольно-печати мой)

<?xml version='1.0' encoding='utf-8'?>
<STUFF xmlns="http://www.company.com">
    <MORE_STUFF>STUFF EVERYWHERE!</MORE_STUFF>
</STUFF>
8 голосов
/ 15 февраля 2011

Мне никогда не удавалось получить тег <?xml из библиотек дерева элементов программно, поэтому я бы посоветовал вам попробовать что-то вроде этого.

from xml.etree import ElementTree as ET
root = ET.Element("STUFF")
root.set('com','http://www.company.com')
body = ET.SubElement(root, "MORE_STUFF")
body.text = "STUFF EVERYWHERE!"

f = open('page.xml', 'w')
f.write('<?xml version="1.0" encoding="UTF-8"?>' + ET.tostring(root))
f.close()

В реализациях ElementTree, не относящихся к стандартным библиотекам Python, могут быть разные способы задания пространств имен, поэтому, если вы решите перейти на lxml, способ объявления этих будет другим.

...