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

使用ET.fromstring解析XML遇ParseError及遍历终止问题求助

解决XML解析PackageReference的两个问题

一、处理xml.etree.ElementTree.ParseError: not well-formed (invalid token)

即便你确认XML格式合规,也可能存在以下隐藏问题,逐一排查:

  • 编码问题:如果XML字符串包含UTF-8 BOM(字节顺序标记),ET.fromstring无法识别,可先去除:
    import codecs
    xml = xml.lstrip(codecs.BOM_UTF8.decode('utf-8'))
    
  • 未转义特殊字符:XML中&、<、>必须转义为&amp;、&lt;、&gt;,检查字符串中是否有未处理的这类字符(比如注释或属性值里的特殊符号)。
  • 不可见控制字符:ASCII控制字符(如\x00-\x1F除换行、制表符)会导致解析失败,用正则过滤:
    import re
    xml = re.sub(r'[\x00-\x08\x0B\x0C\x0E-\x1F]', '', xml)
    

二、解决tree.findall('.//PackageReference')导致程序终止

最常见的原因是XML命名空间未处理,.NET的csproj文件默认带命名空间(如http://schemas.microsoft.com/developer/msbuild/2003),直接用本地名称查找会失败,甚至因未捕获异常导致崩溃,处理方式如下:

  1. 指定命名空间查找:
    import xml.etree.ElementTree as ET
    
    root = ET.fromstring(xml)
    # 提取根元素的命名空间
    ns = {'msbuild': root.attrib['xmlns']}
    # 带命名空间前缀查找元素
    package_refs = root.findall('.//msbuild:PackageReference', namespaces=ns)
    
  2. 捕获异常定位崩溃原因:程序终止大概率是未捕获异常,包裹代码查看具体错误:
    try:
        package_refs = root.findall('.//PackageReference')
        # 后续处理逻辑
    except Exception as e:
        print(f"崩溃原因:{str(e)}")
    
  3. 验证XML结构:确认PackageReference元素的层级是否正确(比如是否嵌套在ItemGroup下),可先打印XML结构:
    ET.dump(root)
    

完整示例代码

import xml.etree.ElementTree as ET
import codecs
import re

def parse_package_references(xml_str):
    # 预处理XML:去除BOM和控制字符
    xml_str = xml_str.lstrip(codecs.BOM_UTF8.decode('utf-8'))
    xml_str = re.sub(r'[\x00-\x08\x0B\x0C\x0E-\x1F]', '', xml_str)
    
    try:
        root = ET.fromstring(xml_str)
        # 处理命名空间
        ns = {}
        if 'xmlns' in root.attrib:
            ns['msbuild'] = root.attrib['xmlns']
        
        # 查找所有PackageReference
        package_refs = root.findall('.//msbuild:PackageReference', namespaces=ns) if ns else root.findall('.//PackageReference')
        
        # 提取Include和Version属性
        result = []
        for ref in package_refs:
            include = ref.attrib.get('Include')
            version = ref.attrib.get('Version')
            if include and version:
                result.append({'Include': include, 'Version': version})
        return result
    except ET.ParseError as e:
        print(f"解析错误:{str(e)}")
        return []
    except Exception as e:
        print(f"程序异常:{str(e)}")
        return []

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 17:12:39