简体   繁体   中英

Add xml subelement with different namespaces than root element using lxml

This is a simplified version of the xml I'm trying to build:

<BizData xmlns="urn:iso:std:iso:20022:tech:xsd:head.003.001.01" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:n1="urn:iso:std:iso:20022:tech:xsd:head.001.001.02" 
  xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:head.003.001.01 head.003.001.02_DTCC.xsd">
  <Hdr>
   <AppHdr xmlns="urn:iso:std:iso:20022:tech:xsd:head.001.001.02"             
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         
    xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:head.001.001.02 head.001.001.02.xsd"> 
   </AppHdr>
  </Hdr>
 </BizData>

Python Code

from lxml import etree as etree

if __name__ == '__main__':
attr_qname = etree.QName('http://www.w3.org/2001/XMLSchema-instance', 'schemaLocation')
nsmap = {None: 'urn:iso:std:iso:20022:tech:xsd:head.003.001.01',
         'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
         'n1': 'urn:iso:std:iso:20022:tech:xsd:head.001.001.02'
        }
root = etree.Element('BizData',
                     {attr_qname: 'urn:iso:std:iso:20022:tech:xsd:head.003.001.01 head.003.001.02_DTCC.xsd'},
                     nsmap)

hdr = etree.Element('hdr')
attr_qname = etree.QName('http://www.w3.org/2001/XMLSchema-instance', 'schemaLocation')
nsmap = {None: 'urn:iso:std:iso:20022:tech:xsd:head.001.001.02',
         'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
         }

app_hdr = etree.Element('AppHdr',
                {attr_qname: 'urn:iso:std:iso:20022:tech:xsd:head.001.001.02 head.001.001.02.xsd'},
                nsmap)
hdr.append(app_hdr)
root.append(hdr)

When printing hdr before appending to the root I get the correct output:

<Hdr>
 <AppHdr xmlns="urn:iso:std:iso:20022:tech:xsd:head.001.001.02"             
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         
  xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:head.001.001.02 head.001.001.02.xsd"> 
 </AppHdr>
</Hdr> 

But after appending to root the namesspaces xmlns and xmlns:xsi disappear:

<BizData xmlns:n1="urn:iso:std:iso:20022:tech:xsd:head.001.001.02" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     
 xmlns="urn:iso:std:iso:20022:tech:xsd:head.003.001.01" 
 xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:head.003.001.01 head.003.001.02_DTCC.xsd">
 <hdr>
  <AppHdr xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:head.001.001.02 head.001.001.02.xsd"/>
 </hdr>
</BizData>

I tried using the set function to set xmlns:xsi but this causes the error ..not a valid attribute...

Does anybody has an idea?

DIRTY WORKAROUND

  1. Create Envelope ( BizData ), Header ( Hdr ) and Payload ( Pyld ) as individual etree.Element 's
  2. Transfer them to strings
  3. Combine the strings
  4. Write to xml file

This is ignoring any sort of validation but doesn't mess with the namespace. Not ideal, but does the job.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM