如何遍历XML文件并计算PremieTot字段的总和
解决XML中PremieTot字段求和问题
问题场景
需要遍历XML文件,计算所有PremieTot字段的数值总和,XML结构示例:
<?xml version="1.0" encoding="iso-8859-1" ?> <Bericht Version="1.0" xmlns="http://www.test.nl/test/2022/01"> <Bericht> <IdBer>1111</IdBer> <IdLcr>2323</IdLcr> <NmLcr>Test Company</NmLcr> </Bericht> <AdministratieveEenheid> <LhNr>3434</LhNr> <NmIP>Test Company</NmIP> <TvkCd>MND</TvkCd> <TijdvakAangifte> <DatAanvTv>2022-01-01</DatAanvTv> <DatEindTv>2022-01-31</DatEindTv> <VolledigeAangifte> <CollectieveAangifte> <TotaalRegelingen> <RelNrAansl>3434</RelNrAansl> </TotaalRegelingen> <TotaalRegelingen> <RelNrAansl>3434</RelNrAansl> </TotaalRegelingen> </CollectieveAangifte> <InkomstenverhoudingInitieel> <NumIV>1</NumIV> <DatAanv>2020-01-01</DatAanv> <PersNr>2364</PersNr> <RegelingGegevens> <PremieTot>0.52</PremieTot> </RegelingGegevens> </InkomstenverhoudingInitieel> <InkomstenverhoudingInitieel> <NumIV>1</NumIV> <DatAanv>2020-07-01</DatAanv> <PersNr>2365</PersNr> <RegelingGegevens> <PremieTot>0.66</PremieTot> <AantVerlUPens>29.12</AantVerlUPens> </RegelingGegevens> </InkomstenverhoudingInitieel> </VolledigeAangifte> </TijdvakAangifte> </AdministratieveEenheid> </Bericht>
尝试用xmltodict解析后无法获取目标字段,代码如下:
info_dict = xml_dict["PensioenAangifte"]["AdministratieveEenheid"]["TijdvakAangifte"]["VolledigeAangifte"] premieTotal = [xml_data["RegelingGegevens"]["PremieTot"] for xml_data in info_dict]
问题原因
- 根节点错误:原代码用
PensioenAangifte作为根节点,但实际XML根节点是Bericht - 命名空间未处理:XML包含默认命名空间
xmlns="http://www.test.nl/test/2022/01",xmltodict解析时会对节点名做特殊处理 - 节点遍历逻辑错误:
VolledigeAangifte下包含CollectieveAangifte等无关节点,直接遍历会导致键不存在错误
解决方案
方法1:修正xmltodict解析逻辑
处理命名空间并修正节点路径,确保目标节点被正确提取:
import xmltodict # 读取XML文件 with open("your_file.xml", "r", encoding="iso-8859-1") as f: xml_content = f.read() # 解析XML,强制将InkomstenverhoudingInitieel转为列表,避免单个节点时出错 xml_dict = xmltodict.parse( xml_content, remove_blank_text=True, force_list={'InkomstenverhoudingInitieel'}, namespaces={'' : 'http://www.test.nl/test/2022/01'} # 映射默认命名空间为空,节点名不带前缀 ) # 逐层获取目标节点列表 volledige_aangifte = xml_dict["Bericht"]["AdministratieveEenheid"]["TijdvakAangifte"]["VolledigeAangifte"] inkomsten_list = volledige_aangifte["InkomstenverhoudingInitieel"] # 计算总和 total_premie = sum(float(item["RegelingGegevens"]["PremieTot"]) for item in inkomsten_list) print(f"PremieTot总和:{total_premie}")
方法2:用lxml结合XPath(更高效)
XPath可直接定位所有PremieTot节点,无需逐层遍历,适合复杂XML结构:
from lxml import etree # 加载XML文件 tree = etree.parse("your_file.xml") # 定义命名空间映射 ns_map = {'ns': 'http://www.test.nl/test/2022/01'} # 提取所有PremieTot节点的文本内容 premie_values = tree.xpath("//ns:PremieTot/text()", namespaces=ns_map) # 计算总和 total_premie = sum(float(val) for val in premie_values) print(f"PremieTot总和:{total_premie}")
内容的提问来源于stack exchange,提问作者saro
相关产品推荐
相关产品推荐

