Python2.7和xml.etree:如何创建具有多个名称空间的xml文件?
我试图创建一个XML文件,使其具有以下框架,最好使用Python 2.7中的XML.etree模块:Python2.7和xml.etree:如何创建具有多个名称空间的xml文件?,python,xml,python-2.7,elementtree,Python,Xml,Python 2.7,Elementtree,我试图创建一个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">
<?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>
....
....
让我烦恼的是“foo…”行。我尝试使用nsmap引入xsi和xsd,但这导致了“无法序列化”错误
我可以构造或修改该行的文本,使其完全符合我的要求,但我想学习使用xml.etree以编程方式实现这一点(在这种情况下,最好不要使用外部库)
我认为这是一种常见的模式,但我在Python和etree中找不到它;您可以调用
register\u 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)
否则,如果需要,您可以显式地设置属性(
ns
dict)。我曾经尝试过类似的操作,不幸的是,xml.etree
太弱了。是否所有的“xmlns:xsi”和“xmlns:xsd”业务都是多余的,因为“thing1”和“thing2”是否仍然没有任何名称空间附加到它们?我只是担心在一个案例中,我会过于简化这一点,而错过了一个学习正确操作的机会(其他案例可能有更严格的要求)。这似乎是可行的(我不太确定我是否需要moredata输出中的“xsi:type=“xsd:string”位,但至少这说明了如何正确设置名称空间)。非常感谢。如果你认为我的问题和你的答案会对其他人有所帮助(我想会的),那么请以同样的方式投票。虽然这个代码片段可能是解决方案,但确实有助于提高你文章的质量。请记住,您将在将来回答读者的问题,这些人可能不知道您的代码建议的原因。
import xml.etree.ElementTree as et
foo = et.Element('foo', **{'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance'}, **{'xmlns:xsd': 'http://www.w3.org/2001/XMLSchema'})
somedata = et.SubElement(foo, 'somedata', bar='1')
moredata = et.SubElement(somedata, 'moredata', whatsit='42')
tree = et.ElementTree(foo)
tree.write('file.xml')