如何通过Python的ElementTree生成XML文件,并在输出中写入注册的名称空间

时间:2019-06-12 11:47:38

标签: python xml xml-parsing elementtree

我需要基于给定的架构生成XML文件。这种模式表明我需要为生成的XML文件中的元素使用名称空间前缀。

出于向后兼容的原因,我需要使用cElementTree。同时,我想漂亮地打印XML输出,即使用缩进。我知道可以通过xml.dom完成。

这是我尝试过的:

import sys
import cElementTree as ET
from xml.dom import minidom
ET.register_namespace('xs', 'http://www.w3.org/2001/XMLSchema')
root = ET.Element('House')
ET.SubElement(root, 'Room')
etreeString = ET.tostring(root, 'utf-8')

以上代码的输出为:

<House><Room /></House>

如何获得标准名称空间正确前缀的元素?另外,如何获取顶部包含XML声明的XML文件?

我尝试创建xml.etree.ElementTree.ElementTree类的实例,以使用write方法,如下所示:

tree = ET.ElementTree(root)
tree.write(sys.stdout)

但是再一次,我没有命名空间:

<House><Room /></House>

最后,如果我尝试在创建每个元素时添加前缀(感觉很奇怪),xml.dom将不会解析它,因为我不知道如何指示使用名称空间前缀进行解析:

>>> kitchenElem = ET.SubElement(root, 'xs:Kitchen')
>>> tree = ET.ElementTree(root)
>>> tree.write(sys.stdout)
<House><Room /><xs:Kitchen /><xs:Kitchen /></House>
>>> etreeString = ET.tostring(root, 'utf-8')
>>> etreeString
'<House><Room /><xs:Kitchen /><xs:Kitchen /></House>'
>>> minidomParsed = minidom.parseString(etreeString)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "ext\vc12_win32\lib\python2.7\site-packages\_xmlplus\dom\minidom.py", line 1925, in parseString
  File "ext\vc12_win32\lib\python2.7\site-packages\_xmlplus\dom\expatbuilder.py", line 942, in parseString
  File "ext\vc12_win32\lib\python2.7\site-packages\_xmlplus\dom\expatbuilder.py", line 223, in parseString
ExpatError: unbound prefix: line 1, column 15

2 个答案:

答案 0 :(得分:1)

要获取正确的前缀名称,请尝试使用QName()

要使用XML声明编写XML,请尝试在ElementTree.write()中使用xml_declaration=True

示例...

Python

import xml.etree.cElementTree as ET

ns = {"xs": "http://www.w3.org/2001/XMLSchema"}

ET.register_namespace('xs', ns["xs"])
root = ET.Element(ET.QName(ns["xs"], "House"))
ET.SubElement(root, ET.QName(ns["xs"], "Room"))

ET.ElementTree(root).write("output.xml", xml_declaration=True, encoding="utf-8")

XML输出

<?xml version='1.0' encoding='utf-8'?>
<xs:House xmlns:xs="http://www.w3.org/2001/XMLSchema"><xs:Room /></xs:House>

注意:您不必使用ns词典。我只是使用它,所以我到处都没有完整的名称空间uri。

答案 1 :(得分:-2)

可以简化XML,不要忘记简单的字符串格式

data = {'Назвние машины':'name', 'Описание':'descript', ...}
list=[data]

strXML='''<document>
'''
xmlTemplate='''<Item>
        <Название>%(Назвние машины)s</Название>
        <Описание>%(Описание)s</Описание>
        <Акция>%(Акция)s</Акция>
        <КоробкаПередач>%(Коробка передач)s</КоробкаПередач>
        <Марка>%(Марка)s</Марка>
        <Модель>%(Модель)s</Модель>
        <Назначение>%(Назначение)s</Назначение>
        <Цена>%(Цена)s</Цена>
        <Фото></Фото>
</Item>'''
for i,data in enumerate(list):
    strXML+=xmlTemplate%data

strXML+='''
</document>'''

结果

<document>
<Item>
        <Название>Назвние машины</Название>
        <Описание>Описание</Описание>
        <Акция>Акция</Акция>
        <КоробкаПередач>Коробка передач</КоробкаПередач>
        <Марка>Марка</Марка>
        <Модель>Модель</Модель>
        <Назначение>Назначение</Назначение>
        <Цена>Цена</Цена>
        <Фото></Фото>
</Item>
</document>

完整代码,如何使用python https://gist.github.com/mrbannyjo/67211c8c94b4a67eec9f4e3ef8cb2c81

用节点列表生成xml