使用xpath获取XML节点的文本给定相邻节点的文本

2024-06-09 03:32:56 发布

您现在位置:Python中文网/ 问答频道 /正文

关于SO的几个帖子很有帮助,但我还没有找到一个能回答这个问题的帖子。你知道吗

我在用Python3和lxml.etree文件你知道吗

给定XML:

<collection xmlns="http://www.loc.gov/MARC21/slim">
<record>
<datafield tag="856" ind1="4" ind2=" ">
<subfield code="y">English</subfield>
<subfield code="s">387115</subfield>
<subfield code="u">
http://some_url/record/1475606/files/COOLPDF-EN.pdf
</subfield>
</datafield>
</record>
</collection>

一个集合包含几百条记录和几十个数据字段(这些都是非常神秘的国会图书馆的东西)

如果一个数据字段有标签856,并且子字段有文本English,我需要节点子字段code=“u”处的链接文本。你知道吗

我试过:

import lxml.etree as ET
ns = '{http://www.loc.gov/MARC21/slim}'
tree = ET.parse('example.xml')
root = tree.getroot()
eng = root.findall(
    './/{0}datafield[@tag="856"]/[{0}descendant::text="English"]/[{0}following-sibling::code="u"]'.format(ns))
print([e.text for e in eng])

但这只是给了我一个空名单。你知道吗

感谢您的帮助。你知道吗

短暂性脑缺血发作


Tags: httpenglishwwwcodemarc21recordlxmlloc
1条回答
网友
1楼 · 发布于 2024-06-09 03:32:56

XPath有几个问题。你知道吗

首先,不能将predicate[])直接放在/之后。你知道吗

其次,descendant::text正在选择一个名为text(在XML中没有)的子元素。类似地,following-sibling::code选择的是名为code的元素,而不是属性。你知道吗

请尝试以下操作:

eng = root.findall('.//{0}datafield[@tag="856"][{0}subfield="English"]/{0}subfield[@code="u"]'.format(ns))

如果您想使用更复杂的XPath,请改用xpath()。例如,如果只想检查文本Englishsubfield属性值为“y”的code元素,可以这样做(这会导致使用findall()的无效谓词错误):

eng = root.xpath('.//s:datafield[@tag="856"][s:subfield[@code="y"]="English"]/s:subfield[@code="u"]', namespaces=ns)

另外,处理名称空间的方式没有问题,但是我发现将前缀映射到名称空间uri更容易;特别是当有多个名称空间时。你知道吗

示例。。。你知道吗

ns = {'s': 'http://www.loc.gov/MARC21/slim'}
eng = root.findall('.//s:datafield[@tag="856"][s:subfield="English"]/s:subfield[@code="u"]', namespaces=ns)

相关问题 更多 >