Reputation: 4330
I have a problem with namespacing in lxml 2.3 and etree.
For example, I have two nodes with different namespaces:
parent = etree.Element('{parent-space}parent')
child = etree.Element('{child-space}child')
After that, child
node is appended to parent
node:
parent.append(child)
Then, if I use tostring
method of etree, I get the following output:
<ns0:parent xmlns:ns0="parent-space">
<ns0:child xmlns:ns0="child-space"/>
</ns0:parent>
Both namespace get the label ns0
here and so they clash. How can I avoid this?
Upvotes: 1
Views: 1265
Reputation: 338326
There is no clash. The ns0
prefix is just overridden for the descendants of <child>
.
This XML document
<ns0:parent xmlns:ns0="parent-space">
<ns0:child xmlns:ns0="child-space"/>
</ns0:parent>
is equivalent to
<ns0:parent xmlns:ns0="parent-space">
<ns1:child xmlns:ns1="child-space"/>
</ns0:parent>
and
<parent xmlns="parent-space">
<child xmlns="child-space"/>
</parent>
as far as the effective namespaces of parent
and child
go.
You could work with an nsmap to declare prefixes. The effective result is the same, but it looks less confusing when serialized.
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)
this prints
<p:parent xmlns:p="http://parent-space.com/" xmlns:c="http://child-space.com/">
<c:child>Some Text</c:child>
</p:parent>
Upvotes: 3
Reputation:
It looks like this post How to tell lxml.etree.tostring(element) not to write namespaces in python? where it is suggested to use cleanup_namespaces
hope this will help
Upvotes: 0