Parse xml file to a python list

Viewed 47

I have a xml file:

<?xml version="1.0" encoding="utf-8" standalone="yes"?> 
 <Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03">
  <CstmrCdtTrfInitn>
    <GrpHdr>
      <MsgId>637987745078994894</MsgId>
      <CreDtTm>2022-09-14T05:48:27</CreDtTm>
      <NbOfTxs>205</NbOfTxs>
      <CtrlSum>154761.02</CtrlSum>
      <InitgPty>
        <Nm> Company</Nm>
      </InitgPty>
    </GrpHdr>
    <PmtInf>
      <PmtInfId>20220914054827-154016</PmtInfId>
      <PmtMtd>TRF</PmtMtd>
      <BtchBookg>true</BtchBookg>
      <NbOfTxs>205</NbOfTxs>
      <CtrlSum>154761.02</CtrlSum>
      <PmtTpInf>
        <SvcLvl>
          <Cd>SEPA</Cd>
        </SvcLvl>
        <CtgyPurp>
          <Cd>SALA</Cd>
        </CtgyPurp>
      </PmtTpInf>
       <CdtTrfTxInf>    <----------------------------------
        <Amt>
          <InstdAmt Ccy="EUR">1536.96</InstdAmt>
        </Amt>
        <Cdtr>
          <Nm>Achternaam, Voornaam </Nm>
        </Cdtr>
        <CdtrAcct>
          <Id>
            <IBAN>NL80RABO0134343443</IBAN>
          </Id>
        </CdtrAcct>
      </CdtTrfTxInf>  <------------------------------------
        <CdtTrfTxInf>    <----------------------------------
        <Amt>
          <InstdAmt Ccy="EUR">1676.96</InstdAmt>
        </Amt>
        <Cdtr>
          <Nm>Achternaam, Voornaam </Nm>
        </Cdtr>
        <CdtrAcct>
          <Id>
            <IBAN>NL80RABO013433222243</IBAN>
          </Id>
        </CdtrAcct>
      </CdtTrfTxInf>  <------------------------------------
   </CstmrCdtTrfInitn>
 </Document>

I use ElementTree:

I want a python list of tuples with the info within the tag (everything between the arrows in the example xml file). So in this example i want al list with 2 tuples.

How can i do that.

I can iterate over the tree, but thats is.

my code:

import xml.etree.ElementTree as ET

tree = ET.parse(xml_file)
root = tree.getroot()

for elem in tree.iter():
    print(elem.tag, elem.text) --> i get every tag in the whole file
2 Answers

I rather like to use xmltodict.

First of all, your input data as given is missing a closing </PmtInf> tag towards the end, just before your closing </CstmrCdtTrfInitn> tag. After fixing that, I saved your xml data into a file and did the following:

import xmltodict

with open("input_data.xml", "r") as f:
    xml_data = f.read()

xml_dict = xmltodict.parse(xml_data)

You can then access the xml data using dictionary accessors, for example:

xml_dict
>>>{'Document': {'@xmlns:xsi': 'http://www.w3.org/20...a-instance', '@xmlns': 'urn:iso:std:iso:2002...001.001.03', 'CstmrCdtTrfInitn': {...}}}

xml_dict["Document"]
>>>{'@xmlns:xsi': 'http://www.w3.org/20...a-instance', '@xmlns': 'urn:iso:std:iso:2002...001.001.03', 'CstmrCdtTrfInitn': {'GrpHdr': {...}, 'PmtInf': {...}}}

xml_dict["Document"]["CstmrCdtTrfInitn"].keys()
>>>dict_keys(['GrpHdr', 'PmtInf'])

xml_dict["Document"]["CstmrCdtTrfInitn"]["PmtInf"]
{'PmtInfId': '20220914054827-154016', 'PmtMtd': 'TRF', 'BtchBookg': 'true', 'NbOfTxs': '205', 'CtrlSum': '154761.02', 'PmtTpInf': {'SvcLvl': {...}, 'CtgyPurp': {...}}, 'CdtTrfTxInf': [{...}, {...}]}
xml_dict["Document"]["CstmrCdtTrfInitn"]["PmtInf"].keys()
dict_keys(['PmtInfId', 'PmtMtd', 'BtchBookg', 'NbOfTxs', 'CtrlSum', 'PmtTpInf', 'CdtTrfTxInf'])

Then you can loop over your CdtTrfTxInf with:

for item in xml_dict["Document"]["CstmrCdtTrfInitn"]["PmtInf"]["CdtTrfTxInf"]:
    print(item)

giving the output:

{'Amt': {'InstdAmt': {'@Ccy': 'EUR', '#text': '1536.96'}}, 'Cdtr': {'Nm': 'Achternaam, Voornaam'}, 'CdtrAcct': {'Id': {'IBAN': 'NL80RABO0134343443'}}}
{'Amt': {'InstdAmt': {'@Ccy': 'EUR', '#text': '1676.96'}}, 'Cdtr': {'Nm': 'Achternaam, Voornaam'}, 'CdtrAcct': {'Id': {'IBAN': 'NL80RABO013433222243'}}}

which you can process as you want.

this is just a speedcode try xd give it a chance and try it :

    import xml.etree.ElementTree as ET

tree = ET.parse("fr.xml")
root = tree.getroot()
test = False
for elem in tree.iter():
    if elem.tag == "CdtTrfTxInf":
        test = True
        continue
    if test and elem.text.strip() :
        print(elem.tag, elem.text)

with result as list of tuple :

import xml.etree.ElementTree as ET

tree = ET.parse("fr.xml")
root = tree.getroot()
test = False
tag = []
textval=[]
for elem in tree.iter():
    if elem.tag == "CdtTrfTxInf":
        test = True
        continue
    if test and elem.text.strip() :
        tag.append(elem.tag)
        textval.append(elem.text)

data = list(zip(tag, textval))
print (data)
Related