lxml xpath() 函数不适用于正确的 XPath 查询
lxml xpath() function does not work with correct XPath query
我正在尝试使用 lxml 库评估一些 XPath 查询,但是,由于某种原因,它似乎不起作用。这是代码
if __name__ == '__main__':
xml = r'''<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<unit xmlns="http://www.srcML.org/srcML/src" revision="0.9.5" language="Java" filename="File.java"><package>package <name><name>com</name><operator>.</operator><name>samples</name><operator>.</operator><name>e978092668</name></name>;</package>
<class><annotation>@<name>Path</name></annotation>
<specifier>public</specifier> class <name>Correct</name> <block>{
<decl_stmt><decl><annotation>@<name>Inject</name></annotation>
<specifier>private</specifier> <type><name>JsonWebToken</name></type> <name>field</name></decl>;</decl_stmt>
}</block></class>
</unit>'''.encode("UTF-8")
xpath = '''unit/class[((descendant-or-self::decl_stmt/decl[(type[name[text()='JsonWebToken']] and annotation[name[text()='Inject']])]) and (annotation[name[text()='Path']]))]'''
tree = etree.fromstring(xml)
a = tree.xpath(xpath)
print(len(a)) # returns 0 (matches)
我在 freeformatter.com 上使用完全相同的 XML 字符串尝试了完全相同的 xpath 查询,它有效并显示了匹配项。我不知道我自己的代码有什么问题,因为大部分情况下,我都是按照网站上的官方教程进行的。
编辑 1:
尝试使用命名空间。
xpath = '''src:unit/src:class[((descendant-or-self::src:decl_stmt/src:decl[(src:type[src:name[text()='JsonWebToken']] and src:annotation[src:name[text()='Inject']])]) and (src:annotation[src:name[text()='Path']]))]'''
tree = etree.fromstring(xml)
a = tree.xpath(xpath, namespaces={
"src": "http://www.srcML.org/srcML/src"
})
print(len(a)) # returns 0 (matches)
谢谢!
问题是当你这样做时:
tree = etree.fromstring(xml)
tree
具有上下文 src:unit
,因此您的 xpath 正在 src:unit
中寻找 child src:unit
。 (如果你 print(tree.tag)
你会看到 {http://www.srcML.org/srcML/src}unit
。)
尝试在 src:class
...
处启动 xpath
xpath = '''src:class[((descendant-or-self::src:decl_stmt/src:decl[(src:type[src:name[text()='JsonWebToken']] and src:annotation[src:name[text()='Inject']])]) and (src:annotation[src:name[text()='Path']]))]'''
我正在尝试使用 lxml 库评估一些 XPath 查询,但是,由于某种原因,它似乎不起作用。这是代码
if __name__ == '__main__':
xml = r'''<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<unit xmlns="http://www.srcML.org/srcML/src" revision="0.9.5" language="Java" filename="File.java"><package>package <name><name>com</name><operator>.</operator><name>samples</name><operator>.</operator><name>e978092668</name></name>;</package>
<class><annotation>@<name>Path</name></annotation>
<specifier>public</specifier> class <name>Correct</name> <block>{
<decl_stmt><decl><annotation>@<name>Inject</name></annotation>
<specifier>private</specifier> <type><name>JsonWebToken</name></type> <name>field</name></decl>;</decl_stmt>
}</block></class>
</unit>'''.encode("UTF-8")
xpath = '''unit/class[((descendant-or-self::decl_stmt/decl[(type[name[text()='JsonWebToken']] and annotation[name[text()='Inject']])]) and (annotation[name[text()='Path']]))]'''
tree = etree.fromstring(xml)
a = tree.xpath(xpath)
print(len(a)) # returns 0 (matches)
我在 freeformatter.com 上使用完全相同的 XML 字符串尝试了完全相同的 xpath 查询,它有效并显示了匹配项。我不知道我自己的代码有什么问题,因为大部分情况下,我都是按照网站上的官方教程进行的。
编辑 1:
尝试使用命名空间。
xpath = '''src:unit/src:class[((descendant-or-self::src:decl_stmt/src:decl[(src:type[src:name[text()='JsonWebToken']] and src:annotation[src:name[text()='Inject']])]) and (src:annotation[src:name[text()='Path']]))]'''
tree = etree.fromstring(xml)
a = tree.xpath(xpath, namespaces={
"src": "http://www.srcML.org/srcML/src"
})
print(len(a)) # returns 0 (matches)
谢谢!
问题是当你这样做时:
tree = etree.fromstring(xml)
tree
具有上下文 src:unit
,因此您的 xpath 正在 src:unit
中寻找 child src:unit
。 (如果你 print(tree.tag)
你会看到 {http://www.srcML.org/srcML/src}unit
。)
尝试在 src:class
...
xpath = '''src:class[((descendant-or-self::src:decl_stmt/src:decl[(src:type[src:name[text()='JsonWebToken']] and src:annotation[src:name[text()='Inject']])]) and (src:annotation[src:name[text()='Path']]))]'''