You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python提取XML标签间值时生成空DataFrame的问题排查

解决XML提取值后生成空DataFrame的问题

首先,你的代码生成空DataFrame最可能的原因是XML命名空间未正确处理——这类金融监管类XML(比如DLTINS格式)几乎都带有默认命名空间,直接用标签名查找元素会找不到匹配项,自然不会有数据添加到rows列表里。下面是具体的排查和修复步骤:

1. 检查并处理XML命名空间

打开你的DLTINS_20210117_01of01.xml文件,开头应该会有类似这样的命名空间声明:

<Document xmlns="urn:iso:std:iso:20022:tech:xsd:dlt.001.001.02">

这意味着所有元素都属于这个命名空间,直接用findall("FinInstrmRptgRefDataDltaRpt")是找不到任何元素的,必须在查找时指定命名空间。

修改代码如下,先提取命名空间,再带命名空间前缀查找:

import xml.etree.ElementTree as ET
import pandas as pd

rows = []
cols = ["Id", "FullNm", "ClssfctnTp", "CmmdtyDerivInd", "NtnlCcy", "Issr"]

# 解析XML并提取命名空间
tree = ET.parse("DLTINS_20210117_01of01.xml")
root = tree.getroot()
# 提取默认命名空间(如果有的话)
ns = {}
if '}' in root.tag:
    ns['ns'] = root.tag.split('}')[0].strip('{')

# 带命名空间查找元素(用.//递归查找任意层级的目标元素)
for i in root.findall(".//ns:FinInstrmRptgRefDataDltaRpt", ns):
    # 查找FinInstrmGnlAttrbts子元素
    j = i.find(".//ns:FinInstrmGnlAttrbts", ns)
    if j is not None:
        # 安全获取标签文本(避免找不到元素时报错)
        Id = j.find("ns:Id", ns).text if j.find("ns:Id", ns) is not None else None
        FullNm = j.find("ns:FullNm", ns).text if j.find("ns:FullNm", ns) is not None else None
        ClssfctnTp = j.find("ns:ClssfctnTp", ns).text if j.find("ns:ClssfctnTp", ns) is not None else None
        CmmdtyDerivInd = j.find("ns:CmmdtyDerivInd", ns).text if j.find("ns:CmmdtyDerivInd", ns) is not None else None
        NtnlCcy = j.find("ns:NtnlCcy", ns).text if j.find("ns:NtnlCcy", ns) is not None else None
        Issr = i.find("ns:Issr", ns).text if i.find("ns:Issr", ns) is not None else None
        
        rows.append({
            "Id": Id,
            "FullNm": FullNm,
            "ClssfctnTp": ClssfctnTp,
            "CmmdtyDerivInd": CmmdtyDerivInd,
            "NtnlCcy": NtnlCcy,
            "Issr": Issr
        })

df = pd.DataFrame(rows, columns=cols)
print(df)

2. 其他可能的排查点

  • 元素路径是否正确:如果修改命名空间后还是空DataFrame,打印root.tag看看根元素是什么,确认FinInstrmRptgRefDataDltaRpt是否直接在根元素下,还是嵌套在其他容器(比如<Document>)里。代码中用.//前缀可以递归查找任意层级的元素,避免路径错误。
  • BeautifulSoup的正确用法:如果你想用BeautifulSoup,同样需要处理命名空间,示例代码如下:
from bs4 import BeautifulSoup
import pandas as pd

rows = []
cols = ["Id", "FullNm", "ClssfctnTp", "CmmdtyDerivInd", "NtnlCcy", "Issr"]

with open("DLTINS_20210117_01of01.xml", "r") as f:
    soup = BeautifulSoup(f, "xml")

# 获取文档的默认命名空间
ns = soup.find().namespace
# 查找所有目标元素
for i in soup.find_all("FinInstrmRptgRefDataDltaRpt", {"xmlns": ns}):
    j = i.find("FinInstrmGnlAttrbts")
    if j:
        Id = j.Id.text if j.Id else None
        FullNm = j.FullNm.text if j.FullNm else None
        ClssfctnTp = j.ClssfctnTp.text if j.ClssfctnTp else None
        CmmdtyDerivInd = j.CmmdtyDerivInd.text if j.CmmdtyDerivInd else None
        NtnlCcy = j.NtnlCcy.text if j.NtnlCcy else None
        Issr = i.Issr.text if i.Issr else None
        
        rows.append({
            "Id": Id,
            "FullNm": FullNm,
            "ClssfctnTp": ClssfctnTp,
            "CmmdtyDerivInd": CmmdtyDerivInd,
            "NtnlCcy": NtnlCcy,
            "Issr": Issr
        })

df = pd.DataFrame(rows, columns=cols)
print(df)

3. 快速验证元素是否存在

可以先执行以下代码,确认是否能找到目标元素:

print(len(root.findall(".//ns:FinInstrmRptgRefDataDltaRpt", ns)))

如果结果是0,说明要么命名空间提取错误,要么元素路径和XML实际结构不匹配,需要进一步查看XML的层级结构。

内容的提问来源于stack exchange,提问作者TotalDark

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 15:52:38