Python 2.7 和 xml.etree:如何创建具有多个命名空间的 XML 文件?

Mar*_*ver 5 python xml elementtree python-2.7

我正在尝试创建一个 XML 文件,使其具有以下骨架,最好使用 Python 2.7 中的 xml.etree 模块:

<?xml version="1.0"?>
<foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" thing1="this" thing2="that">
  ....
  <somedata bar="1">
    <moredata whatsit="42"></moredata>
  </somedata>
  ....
</foo>
Run Code Online (Sandbox Code Playgroud)

令我烦恼的是“foo ....”这句话。我尝试使用 nsmap 引入 xsi 和 xsd,但这导致了“无法序列化”错误。

我可以构造或以其他方式破解该行的文本,使其完全符合我的要求,但我想学习使用 xml.etree 以编程方式执行此操作(在这种情况下,引入外部库并不可取)。

我认为这是一种常见的模式,但我只是没有在 Python 和 etree 的任何地方找到它。

jfs*_*jfs 6

如果文档中使用了前缀;您可以致电register_namespace()添加它们:

import sys
import xml.etree.ElementTree as etree

xsi =  "http://www.w3.org/2001/XMLSchema-instance"
xsd =  "http://www.w3.org/2001/XMLSchema"
ns = {"xmlns:xsi": xsi, "xmlns:xsd": xsd}
for attr, uri in ns.items():
    etree.register_namespace(attr.split(":")[1], uri)

foo = etree.Element("foo",
    dict(thing1="this", thing2="that")) # put `**ns))` if xsi, xsd are unused
somedata = etree.SubElement(foo, "somedata", dict(bar="1"))
etree.SubElement(somedata, "moredata",
    {"whatsit": "42", etree.QName(xsi, "type"): etree.QName(xsd, "string")})

etree.ElementTree(foo).write(sys.stdout, xml_declaration=True)
Run Code Online (Sandbox Code Playgroud)

ns否则,如果需要,您可以显式设置属性(字典)。