GitLab Runner中Python 2的XML findall()解析异常求助
解决思路
1. 显式提取并指定命名空间
放弃依赖{*}通配符,手动从XML根节点提取命名空间后构造XPath,避免环境对通配符的解析差异:
import xml.etree.ElementTree as ET tree = ET.parse('report.fvdl') root = tree.getroot() # 从根节点标签中提取命名空间 ns = root.tag.split('}')[0].strip('{') # 使用显式命名空间查找目标元素 vulns = tree.findall(".//{%s}Vulnerability" % ns)
如果XML包含多个命名空间,可遍历root.nsmap(Python 2.7.10及以上版本支持)获取所有命名空间,逐个尝试匹配。
2. 预处理XML移除命名空间
既然移除命名空间后代码可正常运行,在解析前先预处理XML文本,清除命名空间声明和标签前缀:
with open('report.fvdl', 'r') as f: xml_content = f.read() # 移除默认命名空间声明(替换为实际FVDL的命名空间URL) xml_content = xml_content.replace('xmlns="http://www.fortifysoftware.com/schema/fvdl"', '') # 移除标签中的命名空间前缀 xml_content = xml_content.replace('{http://www.fortifysoftware.com/schema/fvdl}', '') # 解析处理后的XML内容 root = ET.fromstring(xml_content) vulns = root.findall(".//Vulnerability")
3. 升级Python 2的ElementTree库
RHEL 8自带的Python 2.7可能搭载较旧的ElementTree版本,尝试手动安装兼容的更新版:
pip install elementtree==1.3.0
安装完成后重新运行脚本,验证通配符解析是否恢复正常。
4. 改用lxml库替代标准库
lxml对XPath和命名空间的支持更稳定,跨环境表现一致。先安装lxml:
pip install lxml
然后修改代码使用lxml解析:
from lxml import etree tree = etree.parse('report.fvdl') # 通过local-name()忽略命名空间直接匹配元素 vulns = tree.xpath(".//*[local-name()='Vulnerability']") # 或者使用命名空间映射精准匹配 ns_map = {'fvdl': 'http://www.fortifysoftware.com/schema/fvdl'} vulns = tree.xpath(".//fvdl:Vulnerability", namespaces=ns_map)
5. 检查并升级系统XML解析库
RHEL 8上Python 2的XML解析依赖系统的libxml2,若版本过低可能存在解析bug。先查看当前版本:
rpm -q libxml2
若版本低于2.9.0,可尝试升级(注意:升级系统库可能影响其他应用,需谨慎操作):
sudo dnf update libxml2
内容的提问来源于stack exchange,提问作者Tom C
相关产品推荐
相关产品推荐

