使用lxml etree破坏命名空间

时间:2012-09-20 08:22:51

标签: python xml lxml xml-namespaces elementtree

我在lxml 2.3和etree中遇到了命名空间问题。

例如,我有两个具有不同命名空间的节点:

parent = etree.Element('{parent-space}parent')
child = etree.Element('{child-space}child')

之后,child节点将附加到parent节点:

parent.append(child)

然后,如果我使用etree的tostring方法,我得到以下输出:

<ns0:parent xmlns:ns0="parent-space">
    <ns0:child xmlns:ns0="child-space"/>
</ns0:parent>

两个命名空间都在此处获得标签ns0,因此它们会发生冲突。我怎么能避免这个?

2 个答案:

答案 0 :(得分:3)

没有冲突。 ns0的后代只会覆盖<child>前缀。

此XML文档

<ns0:parent xmlns:ns0="parent-space">
    <ns0:child xmlns:ns0="child-space"/>
</ns0:parent>

相当于

<ns0:parent xmlns:ns0="parent-space">
    <ns1:child xmlns:ns1="child-space"/>
</ns0:parent>

<parent xmlns="parent-space">
    <child xmlns="child-space"/>
</parent>

parentchild的有效命名空间而言。

您可以使用nsmap声明前缀。有效的结果是相同的,但在序列化时看起来不那么令人困惑。

from lxml import etree

NS_MAP = {
    "p" : "http://parent-space.com/",
    "c" : "http://child-space.com/"
}
NS_PARENT = "{%s}" % NS_MAP["parent"]
NS_CHILD = "{%s}" % NS_MAP["child"]

parent = etree.Element(NS_PARENT + "parent", nsmap=NS_MAP)
child  = etree.SubElement(parent, NS_CHILD + "child")
child.text = "Some Text"

print etree.tostring(parent, pretty_print=True)

打印

<p:parent xmlns:p="http://parent-space.com/" xmlns:c="http://child-space.com/">
  <c:child>Some Text</c:child>
</p:parent>

答案 1 :(得分:0)

看起来这篇帖子How to tell lxml.etree.tostring(element) not to write namespaces in python?,建议使用cleanup_namespaces

希望这会有所帮助