Search code examples
pythonlxmlxml-namespaces

How to add namespace prefix at root XML using Python LXML?


I would like to have the following NS prefix <qsp: and </qsp:

<qsp:QSPart xmlns:qsp="urn:qvalent:quicksuper:gateway">
  <qsp:MemberRegistrationRequest/>
</qsp:QSPart>

How do I do that in LMXL python?

from lxml import etree

nsmap = {'qsp': 'urn:qvalent:quicksuper:gateway'}
nsprefix = nsmap['qsp']

QSPart = etree.Element('QSPart', nsmap=nsmap)
MemberRegistrationRequest = etree.SubElement(QSPart, etree.QName(nsprefix, 'MemberRegistrationRequest'))

print(etree.tostring(QSPart, pretty_print=True, encoding=str))

Result:

<QSPart xmlns:qsp="urn:qvalent:quicksuper:gateway">
  <qsp:MemberRegistrationRequest/>
</QSPart>

Solution

  • According to the documentation, you need to fully qualify the element name in your call to etree.Element:

    from lxml import etree
    
    nsmap = {'qsp': 'urn:qvalent:quicksuper:gateway'}
    nsprefix = nsmap['qsp']
    
    QSPart = etree.Element(f'{{{nsmap["qsp"]}}}QSPart')
    MemberRegistrationRequest = etree.SubElement(QSPart, etree.QName(nsprefix, 'MemberRegistrationRequest'))
    
    print(etree.tostring(QSPart, pretty_print=True, encoding=str))
    

    This outputs:

    <ns0:QSPart xmlns:ns0="urn:qvalent:quicksuper:gateway">
      <ns0:MemberRegistrationRequest/>
    </ns0:QSPart>