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

转换XML到JSON前如何移除XML命名空间属性?

移除XML命名空间后转换为JSON

我在将XML文件转换为JSON时,发现XML中的命名空间属性(比如xmlns:xsi和xsi:nil)会被带入生成的JSON文件中,希望在转换前移除这些命名空间相关内容。

原始XML代码

<exta>
<sure>This </signature>
<begin_date>2019-07-12T09:41:48.187</begin_date>
<ver>4</ver>
<maiden_bc>1549</maiden_bc>
<exta_id>12345</exta_id>
<nps_max_price xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <exta_id>72723</exta_id>
    <extended_datetime>2018-11-20T11:01:29.040</extended_datetime>
    <event_ind>E</event_ind>
    <maiden>12345</maiden>
    <patient_id>123</patient_id>
    <boss_id>123LHF</boss_id>
    <template_name />
    <end_date>2019-01-01T00:00:00</end_date>
    <UYI_AMN xsi:nil="true" />
    <dedt_bef_ATS xsi:nil="true" />
    <form>W</form>
</exta>

期望处理后的XML代码

<exta>
<sure>This </signature>
<begin_date>2019-07-12T09:41:48.187</begin_date>
<ver>4</ver>
<maiden_bc>1549</maiden_bc>
<exta_id>12345</exta_id>
<nps_max_price>
    <exta_id>72723</exta_id>
    <extended_datetime>2018-11-20T11:01:29.040</extended_datetime>
    <event_ind>E</event_ind>
    <maiden>12345</maiden>
    <patient_id>123</patient_id>
    <boss_id>123LHF</boss_id>
    <template_name />
    <end_date>2019-01-01T00:00:00</end_date>
    <UYI_AMN/>
    <dedt_bef_ATS/>
    <form>W</form>
</exta>

当前Python转换代码

for datafile in bucket.objects.filter(Prefix="test/"):

    if "xml" in datafile.key:
        # converting xml to json
        xml_file = datafile.get()['Body']
        print(datafile.get()['Body'])
        tree = ET.parse(xml_file)
        xml_data = tree.getroot()
        xmlstr = ET.tostring(xml_data, encoding='utf-8', method='xml')
        data_dict = dict(xmltodict.parse(xmlstr, attr_prifix=''))
        json_data = json.dumps(data_dict)

解决方案

方法一:遍历XML节点移除命名空间属性

通过ElementTree遍历所有节点,移除包含命名空间前缀的属性,同时清理xsi:nil标记,生成符合期望的XML后再转换为JSON。

修改后的代码:

import xml.etree.ElementTree as ET
import xmltodict
import json

for datafile in bucket.objects.filter(Prefix="test/"):
    if "xml" in datafile.key:
        xml_file = datafile.get()['Body']
        tree = ET.parse(xml_file)
        root = tree.getroot()

        # 定义需要移除的命名空间属性前缀
        ns_prefixes = ('xmlns:', 'xsi:')

        # 递归遍历所有节点,清理命名空间属性
        def clean_ns(node):
            # 移除当前节点的命名空间相关属性
            attrs_to_delete = [key for key in node.attrib if key.startswith(ns_prefixes)]
            for key in attrs_to_delete:
                del node.attrib[key]
            # 处理子节点
            for child in node:
                clean_ns(child)

        clean_ns(root)

        # 转换为XML字符串并解析为JSON
        xmlstr = ET.tostring(root, encoding='utf-8', method='xml')
        data_dict = xmltodict.parse(xmlstr, attr_prefix='')
        json_data = json.dumps(data_dict)

方法二:解析时直接过滤属性(简化版)

如果不需要保留处理后的XML文件,可在xmltodict解析过程中直接过滤命名空间属性,省去ElementTree遍历步骤。

修改后的代码:

import xmltodict
import json

for datafile in bucket.objects.filter(Prefix="test/"):
    if "xml" in datafile.key:
        xml_content = datafile.get()['Body'].read().decode('utf-8')
        
        # 自定义处理函数,过滤命名空间属性
        def process_node(node):
            # 移除命名空间相关属性
            if '@' in node:
                node['@'] = {k: v for k, v in node['@'].items() if not k.startswith(('xmlns:', 'xsi:'))}
            # 处理xsi:nil标记,转为空值
            if '@xsi:nil' in node:
                node['#text'] = None
                del node['@xsi:nil']
            return node

        data_dict = xmltodict.parse(
            xml_content,
            attr_prefix='',
            postprocessor=process_node
        )
        json_data = json.dumps(data_dict)

说明

  • 方法一适合需要先得到清理后的XML文件的场景,完全匹配期望的XML格式。
  • 方法二更高效,直接在解析为字典的过程中处理属性,仅保留最终JSON结果时优先使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 21:48:18