Python3 XML findall返回空输出,无法获取cpe-23:deprecated-by的type属性
解决思路:修复命名空间缺失问题
我之前处理过类似的CPE字典解析问题,你的代码空输出核心原因是忽略了主CPE命名空间!你的XML里<cpe-list>和<cpe-item>属于主CPE字典的命名空间(通常是http://cpe.mitre.org/dictionary/2.0),但你只在XPath中指定了cpe-23扩展命名空间,导致程序找不到目标元素,自然没有输出。
下面是具体的修复步骤:
1. 确认主命名空间
打开你的XML文件,查看根元素<cpe-list>的xmlns属性,应该类似这样:
<cpe-list xmlns="http://cpe.mitre.org/dictionary/2.0" xmlns:cpe-23="http://scap.nist.gov/schema/cpe-extension/2.3" ...>
这里的http://cpe.mitre.org/dictionary/2.0就是我们需要的主命名空间。
2. 修改代码中的命名空间映射与XPath
把主命名空间加入namespaces参数,同时在XPath中给<cpe-item>加上对应的前缀:
import xml.etree.ElementTree as ET tree = ET.parse(".../official-cpe-dictionary_v2.3.xml") root = tree.getroot() # 同时配置主CPE命名空间和cpe-23扩展命名空间 namespaces = { 'cpe': 'http://cpe.mitre.org/dictionary/2.0', 'cpe-23': 'http://scap.nist.gov/schema/cpe-extension/2.3' } # 给XPath中的cpe-item添加主命名空间前缀 for child in root.findall('cpe:cpe-item/cpe-23:cpe23-item/cpe-23:deprecation/cpe-23:deprecated-by', namespaces=namespaces): print(child.attrib['name'], child.attrib['type'])
3. 分步排查小技巧
如果还是有问题,可以逐层验证XPath是否生效:
- 先尝试查找所有
<cpe-item>:root.findall('cpe:cpe-item', namespaces=namespaces),确认返回非空列表 - 再深入到
<cpe23-item>:root.findall('cpe:cpe-item/cpe-23:cpe23-item', namespaces=namespaces) - 以此类推,逐步定位哪一层出现了匹配问题
另外,你可以打印root.tag来确认主命名空间是否正确——如果输出是{http://cpe.mitre.org/dictionary/2.0}cpe-list,就说明我们的命名空间配置是对的。
这样修改后,应该就能正常获取到<deprecated-by>标签的name和type属性了。
内容的提问来源于stack exchange,提问作者Melvin
相关产品推荐
相关产品推荐

