1

Ok, this should be simple, but I cant figure it out. How do I add a namespace to an already created element?

If I have:

myxml = '<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<p:obj xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main">
<p:part>Part1</p:part></p:obj>'

root = XML(myxml)

Using lxml, how do I add the additional namespace?

xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"

So the result xml should look like:

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<p:obj xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<p:part>Part1</p:part></p:obj>`

Please note that I need to add to an already created element.

rolfl
  • 17,539
  • 7
  • 42
  • 76
  • You have nested single quotes in your `myxml` string. Replace the quotes around `1.0`, `UTF-8`, and `yes` with double quotes. You will probably also want to use triple quotes around this multi-line string. – ChrisGPT was on strike Dec 24 '13 at 18:37

2 Answers2

1

What you want is answered here. However, it uses the xml package. You can achieve the same results very similarly with the lxml package.

from lxml import etree
etree.register_namespace('a',"http://schemas.openxmlformats.org/drawingml/2006/main")
myxml = "<?xml version='1.0' encoding='UTF-8' standalone='yes'?><p:obj xmlns:p='http://schemas.openxmlformats.org/presentationml/2006/main'><p:part>Part1</p:part></p:obj>"
root = etree.XML(myxml)

Since

Community
  • 1
  • 1
nfazzio
  • 498
  • 1
  • 3
  • 12
  • Yes, its easy to change or add namespaces *before* we create the element. The trick here was to change it *after* its created. – user3133108 Dec 24 '13 at 23:39
0

The nsmap for an element is read only so it cannot be updated after the element has been created in lxml. From the docs...

Therefore, modifying the returned dict cannot have any meaningful impact on the Element. Any changes to it are ignored.

It might be simpler for you in the long run to construct the nsmap up front, add it to your root and then add the children. If you only input is the xml string this probably means a tiny bit more work and you will have to parse the child elements. If this is a really big document you will want to look at iterparse.

Chris A
  • 28
  • 1
  • 5
  • Yea, looking at it more, that is what I find. Once you have the element created, noway to change the nsmap. Argg! There should be some call like Element.set_nsmap(dict) or some such. So I have to load up all the possible namespaces I want upfront like you suggest. This seems to be the only solution here. Thx! – user3133108 Dec 24 '13 at 23:37