【问题标题】:Python 2.7 and xml.etree: how to create an XML file with multiple namespaces?Python 2.7 和 xml.etree:如何创建具有多个命名空间的 XML 文件?
【发布时间】:2013-06-09 16:08:03
【问题描述】:

我正在尝试创建一个 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>

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

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

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

【问题讨论】:

  • 我曾经尝试做类似的事情,不幸的是,xml.etree 似乎太弱了。
  • 是否所有“xmlns:xsi”和“xmlns:xsd”业务都是多余的,因为“thing1”和“thing2”无论如何都没有附加任何命名空间?我只是担心我会在一个案例中过于简单化,而错过学习正确操作的机会(其他案例可能有更严格的要求)。

标签: python xml python-2.7 elementtree


【解决方案1】:
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')

【讨论】:

  • 虽然此代码 sn-p 可能是解决方案,但 including an explanation 确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
【解决方案2】:

如果文档中使用了前缀;你可以打电话给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)

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

【讨论】:

  • 这似乎有效(我不太确定我是否需要 moredata 输出中的 "xsi:type="xsd:string"" 位,但至少这显示了如何设置命名空间正确)。谢谢!如果您认为我的问题和您的回答会帮助其他人(我认为会),请以实物形式投票。
猜你喜欢
  • 2020-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-29
  • 2014-02-07
相关资源
最近更新 更多