Using namespaces with lxml.etree

I need to admit, when I initiated and released ruledxml for the first time, I didn’t care much about namespaces. The usecase was not prevalent in my setting. This changed now.

Time to implement it properly and so I need to look at handling XML namespaces with python’s lxml.etree in more detail. In the following you can see a cheatsheet how you achieve a certain XML namespaced output with lxml.etree.Element instances.

The following table always shows a desired result following by the python source code to generate it.

<a><b/></a>
>>> a = lxml.etree.Element('a')
>>> b = lxml.etree.Element('b')
>>> a.append(b)
>>> lxml.etree.tostring(a)
b'<a><b/></a>'
<a xmlns="http://example.org/">
  <b/>
</a>
>>> a = lxml.etree.Element('a', nsmap={None: 'http://example.org/'})
>>> b = lxml.etree.Element('b')
>>> a.append(b)
>>> lxml.etree.tostring(a)
b'<a xmlns="http://example.org/"><b/></a>'
<a xmlns:ex="http://example.org/">
  <ex:b/>
</a>
>>> a = lxml.etree.Element('a',
...   nsmap={'ex': 'http://example.org/'})
>>> b = e('{http://example.org/}b')
>>> a.append(b)
>>> lxml.etree.tostring(a)
b'<a xmlns:ex="http://example.org/"><ex:b/></a>'
<ex:a xmlns:ex="http://example.org/">
  <ex:b/>
</ex:a>
>>> a = lxml.etree.Element('{http://example.org/}a',
...   nsmap={'ex': 'http://example.org/'})
>>> b = e('{http://example.org/}b')
>>> a.append(b)
>>> lxml.etree.tostring(a)
b'<ex:a xmlns:ex="http://example.org/"><ex:b/></ex:a>'
<ex:a xmlns:ex="http://example.org/" ex:attr="value">
  <ex:b/>
</ex:a>
>>> a = lxml.etree.Element('{http://example.org/}a',
...   nsmap={'ex': 'http://example.org/'})
>>> a.attrib['{http://example.org/}attr'] = 'value'
>>> a.append(b)
>>> lxml.etree.tostring(a)
b'<ex:a xmlns:ex="http://example.org/"
   ex:attr="value"><ex:b/></ex:a>'
<ex:a xmlns:ex="http://example.org/example"
      xmlns:org="http://example.org/organization"
      ex:attr="value">
  <org:b ex:example="value1" org:example="value2"/>
</ex:a>
>>> a = lxml.etree.Element('{http://example.org/example}a',
...   nsmap={'ex': 'http://example.org/example',
...          'org': 'http://example.org/organization'})
>>> a.attrib['{http://example.org/example}attr'] = 'value'
>>> b = lxml.etree.Element('{http://example.org/organization}b')
>>> b.attrib['{http://example.org/example}example'] = 'value1'
>>> b.attrib['{http://example.org/organization}example'] = 'value2'
>>> a.append(b)
>>> lxml.etree.tostring(a)
b'<ex:a xmlns:ex="http://example.org/example"
        xmlns:org="http://example.org/organization"
        ex:attr="value">
    <org:b ex:example="value1" org:example="value2"/></ex:a>'
<a xmlns:ex="http://example.org/" xml:lang="ja">
  <ex:b/>
</a>
>>> a = lxml.etree.Element('a',
...   nsmap={'ex': 'http://example.org/'})
>>> a.attrib["{http://www.w3.org/XML/1998/namespace}lang"] = 'ja'
>>> b = lxml.etree.Element('{http://example.org/}b')
>>> a.append(b)
>>> lxml.etree.tostring(a)
b'<a xmlns:ex="http://example.org/" xml:lang="ja"><ex:b/></a>'
<a xmlns:ex="http://example.org/" xml:lang="ja">
  <ex:b xml:lang="en"/>
</a>
>>> a = lxml.etree.Element('a',
...   nsmap={'ex': 'http://example.org/'})
>>> a.attrib["{http://www.w3.org/XML/1998/namespace}lang"] = 'ja'
>>> b = lxml.etree.Element('{http://example.org/}b')
>>> b.attrib["{http://www.w3.org/XML/1998/namespace}lang"] = 'en'
>>> a.append(b)
>>> lxml.etree.tostring(a)
b'<a xmlns:ex="http://example.org/" xml:lang="ja"><ex:b
  xml:lang="en"/></a>'
Using namespaces with lxml.etree

Leave a Reply

Your email address will not be published. Required fields are marked *