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

时间:2016-07-08 09:57:51

标签: python dom namespaces xml-namespaces minidom

我想使用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?我忘了什么吗?

1 个答案:

答案 0 :(得分:1)

完全披露:我不使用minidom用于XML,我使用lxml并且最重要的是我不经常使用XML,所以我希望我的答案有用。

  

有人可能期望通过设置具有特定命名空间的属性,就不需要在最终编写的XML文档中显式地声明出现在本地名称之前的前缀 - 毕竟,应该可以检测到已使用名称空间,并且在完整属性名称中需要前缀,以便将该属性识别为与该名称空间相关联。不幸的是,我们似乎没有那么奢侈,在设置这样的属性时必须明确指定前缀作为限定名称的一部分

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

这可以解决您的问题:

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

如您所知,setAttributeNS方法有三个参数:namespaceURI,qualifiedName,value。如果元素没有具有相同namespaceURI和localname的属性,则添加该属性 - 我们通过使用函数_nssplit对qualifiedName进行拆分来获取localname。否则,该方法会尝试更新属性的值。

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

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

我有一个问题:为什么要约束root = document.appendChild(root_xml)?是否要避免REPL中的返回值?我明白了。