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

如何在带XML命名空间的ElementTree中遍历根节点获取ClsItems标签

问题原因

你遇到的问题是XML根节点定义了无前缀的默认命名空间,所有未加前缀的标签都会自动归属到该命名空间下,直接搜索ClsItems无法匹配的原因是标签实际的完整标识为{http://ws.comax.co.il/Comax_WebServices/}ClsItems,并非单纯的ClsItems。


解决方案

方案1:显式声明命名空间映射(推荐)

这是符合XML规范的处理方式,不会修改原XML结构:

  • 自定义命名空间字典,给默认命名空间绑定一个自定义前缀
  • 所有find/findall查询时,标签前加自定义前缀,同时传入命名空间参数
import xml.etree.ElementTree as ET

# 命名空间映射:自定义前缀对应XML里的默认命名空间地址
ns = {
    "ws": "http://ws.comax.co.il/Comax_WebServices/"
}

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

# 注意原XML中ID字段是大写,和标签名保持一致
product_dict = { "Name": [], "Size": [], 'ID': []}

# 查询时添加前缀,传入命名空间参数
for idx, item in enumerate(root.findall('.//ws:ClsItems', namespaces=ns)):
    for field in product_dict.keys():
        # 子字段查询也需要加命名空间前缀
        field_node = item.find(f'ws:{field}', namespaces=ns)
        product_dict[field].append(field_node.text if field_node is not None else None)

方案2:统一清除命名空间前缀

如果不想每次查询都加前缀,可以先批量移除所有标签的命名空间标识,直接沿用你原来的代码逻辑:

import xml.etree.ElementTree as ET

def remove_namespace(tree):
    for elem in tree.iter():
        # 拆分标签中的命名空间前缀,保留原始标签名
        if '}' in elem.tag:
            elem.tag = elem.tag.split('}', 1)[1]
    return tree

tree = ET.parse(xml_path)
root = remove_namespace(tree).getroot()

# 后续直接使用你原有的逻辑即可
headers = []
product_dict = { "Name": [], "Size": [], 'ID': []}
for idx, item in enumerate(root.findall('.//ClsItems')):
   if idx == 0:
        headers = [x.tag for x in list(item)]
   for h in headers:
        if h in product_dict:
             product_dict[h].append(item.find(h).text)

注意:你原有代码中product_dict的键写为小写开头的Id,但XML中对应标签是大写ID,大小写不匹配会导致取值失败,需要修正字段名。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 15:06:00