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

Python解析带命名空间嵌套XML:提取mfgr值生成零件号字典

解决带命名空间XML解析问题并生成零件-厂商字典

场景与需求

通过API查询零件号后,返回带命名空间的嵌套XML(精简结构如下),需要将每个零件号作为键,对应<mfgr>元素的文本作为值,生成格式类似{"samplepart1": "manufacturer1", "samplepart2": "manufacturer2"}的字典。

XML示例:

<ArrayOfitem xmlns="WhereDataComesFrom.com" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <item>
        <associateditem_swap/>
        <bulk>false</bulk>
        <category>Memory</category>
        <clei>false</clei>
        <createddate>5/11/2021 7:34:58 PM</createddate>
        <description>sample description</description>
        <heci/>
        <imageurl/>
        <item_swap/>
        <itemid>1640</itemid>
        <itemnumber>**sample part number**</itemnumber>
        <listprice>0.0000</listprice>
        <manufactureritem/>
        <maxavailable>66</maxavailable>
        <mfgr>**sample manufacturer**</mfgr>
        <minreorderqty>0</minreorderqty>
        <noninventory>false</noninventory>
        <primarylocation/>
        <reorderpoint>0</reorderpoint>
        <rep>AP</rep>
        <type>Memory                                  </type>
        <updateddate>2/4/2022 2:22:51 PM</updateddate>
        <warehouse>MAIN</warehouse>
    </item>
</ArrayOfitem>

现有API请求代码

当前用于循环请求API的Python代码:

import http.client
import xml.etree.ElementTree as etree

pn_list = ["samplepart1", "samplepart2"]
api_key = "**redacted lol**"

def getMFGR():
    global raw_xml
    for part_number in pn_list:
        conn = http.client.HTTPSConnection("api.website.com")
        payload = ''
        headers = {
            'session-token': api_key,  # 原代码误写为字符串'api_key',此处修正为变量
            'Cookie': 'firstpartofmycookie; secondpartofmycookie'
        }
        conn.request("GET", f"/webapi.svc/MI/XML/GetItemsByItemNumber?ItemNumber={part_number}", payload, headers)
        res = conn.getresponse()
        data = res.read()
        raw_xml = data.decode("utf-8")
        print(raw_xml)
        print()

getMFGR()

遇到的解析错误

尝试的解析代码放入循环后出现列表索引越界错误,核心原因是XML路径定位错误:<mfgr>元素并非直接在根节点<ArrayOfitem>下,而是嵌套在<item>节点内,且未正确遍历层级。

root = etree.fromstring(raw_xml)
my_ns = {'root': 'WhereDataComesFrom.com'}

mfgr = root.findall('root:mfgr', my_ns)[0].text  # 错误路径:根节点下无直接的mfgr元素

修正后的完整解决方案

以下是整合请求与解析逻辑的代码,解决命名空间定位问题并生成目标字典:

import http.client
import xml.etree.ElementTree as etree

pn_list = ["samplepart1", "samplepart2"]
api_key = "**redacted lol**"
part_manufacturer_dict = {}  # 存储最终结果的字典
NS = {'ns': 'WhereDataComesFrom.com'}  # 定义命名空间别名

def get_mfgr_for_parts():
    for part_number in pn_list:
        conn = http.client.HTTPSConnection("api.website.com")
        payload = ''
        headers = {
            'session-token': api_key,
            'Cookie': 'firstpartofmycookie; secondpartofmycookie'
        }
        # 用f-string拼接URL更简洁易读
        url = f"/webapi.svc/MI/XML/GetItemsByItemNumber?ItemNumber={part_number}"
        conn.request("GET", url, payload, headers)
        res = conn.getresponse()
        data = res.read().decode("utf-8")
        
        # 解析XML
        root = etree.fromstring(data)
        # 按层级定位mfgr:先找item节点,再在其下找mfgr
        mfgr_element = root.find('ns:item/ns:mfgr', NS)
        
        # 处理元素不存在的情况,避免索引越界
        if mfgr_element is not None and mfgr_element.text is not None:
            part_manufacturer_dict[part_number] = mfgr_element.text.strip()
        else:
            part_manufacturer_dict[part_number] = "Unknown Manufacturer"  # 也可根据需求设为None
    
    # 输出最终字典
    print(part_manufacturer_dict)

get_mfgr_for_parts()

关键修正点:

  1. 命名空间路径修正:使用ns:item/ns:mfgr的层级路径,正确定位嵌套在<item>下的<mfgr>元素
  2. 避免索引越界:改用find()而非findall()[0],直接返回单个元素,通过判断元素是否存在处理异常情况
  3. 代码规范优化:移除全局变量raw_xml,改用字典直接存储结果;修正原代码中session-token值的错误;用f-string拼接URL提升可读性
  4. 文本处理:用strip()去除<mfgr>文本可能存在的多余空格

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 23:25:18