如何用ElementTree解析XML生成<CdtTrfTxInf>内容的Python元组列表
问题描述
我有一个指定结构的XML文件,用Python的ElementTree库处理时目前只能遍历整个XML树,现在需要提取所有<CdtTrfTxInf>标签内的信息,生成包含元组的Python列表(示例里有2个<CdtTrfTxInf>,最终要生成2个元组)。现有代码如下:
import xml.etree.ElementTree as ET tree = ET.parse(xml_file) root = tree.getroot() for elem in tree.iter(): print(elem.tag, elem.text) # 输出文件中所有标签
对应的XML文件结构:
<?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>
解决方案
这个XML带有默认命名空间,直接用标签名查找会找不到目标元素,必须先处理命名空间,再提取所需字段。以下是实现代码:
import xml.etree.ElementTree as ET # 定义XML的默认命名空间,用别名简化书写 NS = {'ns': 'urn:iso:std:iso:20022:tech:xsd:pain.001.001.03'} xml_file = 'your_file_path.xml' # 替换成你的XML文件实际路径 tree = ET.parse(xml_file) root = tree.getroot() # 存储交易信息的元组列表 transaction_list = [] # 递归查找所有<CdtTrfTxInf>标签 for tx_node in root.findall('.//ns:CdtTrfTxInf', namespaces=NS): # 提取交易金额 amount = tx_node.find('.//ns:InstdAmt', NS).text # 提取收款人姓名,去掉前后空格 payee_name = tx_node.find('.//ns:Nm', NS).text.strip() # 提取收款人IBAN iban = tx_node.find('.//ns:IBAN', NS).text # 将信息打包成元组,加入列表 transaction_list.append((amount, payee_name, iban)) # 打印结果 for item in transaction_list: print(item)
代码说明
- 命名空间处理:XML里的
xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03"是默认命名空间,ElementTree需要通过命名空间字典来匹配标签,这里用ns作为别名简化代码。 - 定位目标标签:用
root.findall('.//ns:CdtTrfTxInf', NS)递归查找XML中所有层级的<CdtTrfTxInf>标签。 - 提取字段:对每个交易标签,用
find方法结合命名空间定位到<InstdAmt>、<Nm>、<IBAN>子标签,提取文本内容。 - 生成元组列表:把每个交易的三个字段打包成元组,添加到列表中,最终得到符合要求的结果。
运行后会输出两个元组:
('1536.96', 'Achternaam, Voornaam', 'NL80RABO0134343443') ('1676.96', 'Achternaam, Voornaam', 'NL80RABO013433222243')
内容的提问来源于stack exchange,提问作者saro
相关产品推荐
相关产品推荐

