python - 使用 xpath 获取给定相邻节点文本的 XML 节点文本
问题描述
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 并且具有带有文本英语的子字段,我想要节点子字段代码 =“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])
但这只是给了我一个空列表。
任何帮助表示赞赏。
TIA
解决方案
您的 XPath 存在一些问题。
首先,您不能将谓词( []
) 直接放在 a 之后/
。
其次,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()
改用。例如,如果您只想检查text 属性值为“y”的subfield
元素,您可以这样做(这会导致使用 的无效谓词错误):code
English
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)
推荐阅读
- python - 如何在 Python 中循环遍历 3D NIFTI 图像
- mysql - 试图连接 asp.net 和 mysql 试图找出 mysql.data.dll
- angular - Angular 7 Material DatePicker 无法使用 DRF 格式化
- reactjs - 使用 React 获取 csrftoken cookie
- c# - C#~如何读取MultiLevelPointer?
- c# - 如何从 Xamarin.IOS UIImage 获取像素数据?
- c# - Dispatcher.Invoke 是否在内部调用 CheckAccess?
- python - 我可以使用 plotly 仅绘制 3D 坐标吗?
- macos - 如何在 Mac OS 上使用 Qt Designer 设置 Qwt 6.1.3?
- asp.net-mvc - MVC 为什么 Kendo 捆绑有时有效有时无效