Martin
Martin

Reputation: 4330

Clashing namespaces with lxml etree

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

Answers (2)

Tomalak
Tomalak

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

user1593705
user1593705

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

Related Questions