Jakebut Jakebut - 1 month ago 4
Python Question

Generating xml with LXML - attribute namespace

I need to generate xml which looks like this:

<definitions xmlns:ex="http://www.example1.org" xmlns="http://www.example2.org">
<typeRef xmlns:ns2="xyz">text</typeRef>
</definitions>


My code looks as follows:

class XMLNamespaces:
ex = 'http://www.example1.org'
xmlns = 'http://www.example2.org'

root = Element('definitions', xmlns='http://www.example2.org', nsmap = {'ex':XMLNamespaces.ex})
type_ref = SubElement(root, 'typeRef')
type_ref.attrib[QName(XMLNamespaces.xmlns, 'ns2')] = 'xyz'
type_ref.text = 'text'

tree = ElementTree(root)
tree.write('filename.xml', pretty_print=True)


The result looks like:

<definitions xmlns:ex="http://www.example1.org" xmlns="http://www.example2.org">
<typeRef xmlns:ns0="http://www.example2.org" ns0:ns2="xyz">text</typeRef>
</definitions>


So here is my question:

How to make attribute look like xmlns:ns2="xyz" instead of xmlns:ns0="http://www.example2.org" ns0:ns2="xyz"?

Answer

Simply run same process as your opening element where you defined the namespace dictionary with nsmap argument. Notice the added variable in your class object:

from lxml.etree import *

class XMLNamespaces:
    ex = 'http://www.example1.org' 
    xmlns = 'http://www.example2.org'
    xyz = 'xyz'

root = Element('definitions', xmlns='http://www.example2.org', nsmap={'ex':XMLNamespaces.ex})
type_ref = SubElement(root, 'typeRef', nsmap={'ns2':XMLNamespaces.xyz})
type_ref.text = 'text'

tree = ElementTree(root)
tree.write('filename.xml', pretty_print=True)

# <definitions xmlns:ex="http://www.example1.org" xmlns="http://www.example2.org">
#   <typeRef xmlns:ns2="xyz">text</typeRef>
# </definitions>
Comments