将命名空间添加到 DOM 元素 python

Adding Namespaces to a DOM Element python

我想用 pythonminidom:

生成这个 xml 文件
<xml vesion="1.0" encoding="utf-8?>
<package name="Operation" xmlns="http://www.modelIL.eu/types-2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.modelIL.eu/types-2.0 modelIL-package-2.0.xsd">
</package>

我写了这个:

import xml.dom.minidom as dom

document = dom.Document()
root_xml = document.createElement("package")
root_xml.setAttribute("name", "Operation")
root_xml.setAttributeNS("", "xmlns", "http://www.modelIL.eu/types-2.0")
root_xml.setAttributeNS("xmls", "xsi", "http://www.w3.org/2001/XMLSchema-instance")
root_xml.setAttribute("xsi:schemaLocation", "http://www.modelIL.eu/types-2.0 modelIL-package-2.0.xsd")
root = document.appendChild(root_xml)

print(document.toprettyxml(indent("    "))

但我得到的输出是这个:

<xml vesion="1.0" ?>
<package name="Operation" xmlns="http://www.modelIL.eu/types-2.0" xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.modelIL.eu/types-2.0 modelIL-package-2.0.xsd">
</package>

为什么我只有 xsi 而没有 xmlns:xsi?我是不是忘记了什么?

完全披露:我不为 XML 使用 minidom,我使用 lxml 而且我不经常使用 XML,所以希望我的回答对你有用。

One might expect that by setting an attribute with a particular namespace, there would not be any need to explicitly state a prefix to appear before the local name in the final, written XML document - after all, it should be possible to detect that a namespace has been employed and that a prefix is required in the full attribute name so that the attribute is recognised as being associated with that namespace. Unfortunately, we do not seem to have that luxury and must explicitly specify a prefix as part of the qualified name when setting such an attribute

Python and XML: An Introduction(跳到属性部分)

这应该可以解决您的问题:

root_xml.setAttributeNS("xmls", "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")

如你所知setAttributeNS method takes three arguments: namespaceURI, qualifiedName, value. The attribute is than added if the element has no attribute with the same namespaceURI and localname - we get the localname by doing a split on qualifiedName using the function _nssplit。否则该方法会尝试更新属性的值。

然而,属性的名称是前缀(冒号标点符号之前的 qualifiedName 部分)和本地名称 "%s:%s" % (prefix, localName) 的组合。如果不存在前缀,则属性名称与 qualifiedName 参数相同。

如果您不关心属性的 namespaceURI,您可以只使用 setAttribute 方法获得与第一个和最后一个属性相同的结果。在这种情况下,该方法将查找具有相同属性名称的属性。如果找到一个,它将尝试覆盖它的值。

我有一个问题:为什么要绑定 root = document.appendChild(root_xml)?是为了避免 REPL 中的 return 值吗?我明白了。