使用Python xml.etree.ElementTree的root.find()查找XML标签失败求助
解决XML带命名空间下查找
<issn>元素的问题 问题原因
你的XML根节点OAI-PMH带有命名空间http://www.openarchives.org/OAI/2.0/,XML中所有子节点默认继承该命名空间。直接调用find("issn")会查找无命名空间的<issn>元素,自然匹配不到,所以返回None。
解决方案
方法1:带命名空间递归查找并筛选属性
先提取根节点的命名空间,再用带命名空间的路径递归查找所有<issn>,最后筛选目标属性:
import xml.etree.ElementTree as ET tree = ET.parse("bib_full-001664.xml") root = tree.getroot() # 提取根节点的命名空间 ns = {"oai": root.tag.split('}')[0].strip('{')} # 递归查找所有带命名空间的issn元素,筛选pub-type为ppub的 for issn in root.findall(".//oai:issn", ns): if issn.get("pub-type") == "ppub": print(issn.text) # 输出:2544-1558
方法2:用XPath直接定位目标元素
如果要精准匹配pub-type="ppub"的<issn>,可以直接用XPath的属性筛选语法一步到位:
import xml.etree.ElementTree as ET tree = ET.parse("bib_full-001664.xml") root = tree.getroot() ns = {"oai": root.tag.split('}')[0].strip('{')} # 直接定位符合条件的第一个issn元素 target_issn = root.find(".//oai:issn[@pub-type='ppub']", ns) if target_issn: print(target_issn.text) # 输出:2544-1558
方法3:忽略命名空间查找(不推荐)
如果不想处理命名空间,也可以通过匹配标签名后缀来查找,但这种方法不够严谨,多命名空间场景下容易出错:
import xml.etree.ElementTree as ET tree = ET.parse("bib_full-001664.xml") root = tree.getroot() # 遍历所有节点,匹配标签名以issn结尾的元素 for elem in root.iter(): if elem.tag.endswith('issn') and elem.get("pub-type") == "ppub": print(elem.text)
关键说明
.//在XPath中表示递归查找所有后代节点,无需手动数标签层级,适配嵌套较深的XML结构- 命名空间字典的键(比如示例中的
oai)可自定义,只要与XPath中的前缀对应即可 findall返回所有匹配元素,find仅返回第一个匹配元素
内容的提问来源于stack exchange,提问作者Adam Jurkiewicz
相关产品推荐
相关产品推荐

