Python lxml XPath:前面的关键字没有给出预期的结果
Python lxml XPath : preceding keyword does not give expected result
我正在尝试按如下方式解析 xml 文档
import re
from lxml.html.soupparser import fromstring
inString = """
<doc>
<q></q>
<p1>
<p2 dd="ert" ji="pp">
<p3>1</p3>
<p3>2</p3>
<p3>ABC</p3>
<p3>3</p3>
</p2>
<p2 dd="ert" ji="pp">
<p3>4</p3>
<p3>5</p3>
<p3>ABC</p3>
<p3>6</p3>
</p2>
</p1>
<r></r>
<p1>
<p2 dd="ert" ji="pp">
<p3>7</p3>
<p3>8</p3>
<p3>ABC</p3>
<p3>9</p3>
</p2>
<p2 dd="ert" ji="pp">
<p3>10</p3>
<p3>11</p3>
<p3>ABC</p3>
<p3>12</p3>
</p2>
</p1>
</doc>
"""
root = fromstring(inString)
nodes = root.xpath("./doc//p1/p2/p3[contains(text(),'ABC')]//preceding::p2//p3")
print " ".join([re.sub('[\s+]', ' ', para.text.encode('utf-8').strip()) for para in nodes])
所以,对于每个 <p1>
标签,我想到达 <p2>
内的 <p3>
个标签。然后我只想要 <p3>
标签直到标签有像 ABC
这样的文本。但是,如果我 运行 上面的代码,我得到
1 2 ABC 3 4 5 ABC 6 7 8 ABC 9
期望的输出是
1 2 4 5 7 8 10 11
此外,如果我进行此更改
nodes = root.xpath("./doc//p1/p2/p3[contains(text(),'ABC')]")
我得到
ABC ABC ABC ABC
所以看起来第二种方法能够根据 xpath 从整个文档中获取所有 <p3>
节点,这很好。为什么我的第一个查询不起作用?
如何获得所需的输出?
找到包含 ABC
的 p3
后,您无需爬上树 - 只需使用 preceding-sibling
前往 "sideways":
./doc//p1/p2/p3[contains(text(),'ABC')]/preceding-sibling::p3
打印 1 2 4 5 7 8 10 11
.
我正在尝试按如下方式解析 xml 文档
import re
from lxml.html.soupparser import fromstring
inString = """
<doc>
<q></q>
<p1>
<p2 dd="ert" ji="pp">
<p3>1</p3>
<p3>2</p3>
<p3>ABC</p3>
<p3>3</p3>
</p2>
<p2 dd="ert" ji="pp">
<p3>4</p3>
<p3>5</p3>
<p3>ABC</p3>
<p3>6</p3>
</p2>
</p1>
<r></r>
<p1>
<p2 dd="ert" ji="pp">
<p3>7</p3>
<p3>8</p3>
<p3>ABC</p3>
<p3>9</p3>
</p2>
<p2 dd="ert" ji="pp">
<p3>10</p3>
<p3>11</p3>
<p3>ABC</p3>
<p3>12</p3>
</p2>
</p1>
</doc>
"""
root = fromstring(inString)
nodes = root.xpath("./doc//p1/p2/p3[contains(text(),'ABC')]//preceding::p2//p3")
print " ".join([re.sub('[\s+]', ' ', para.text.encode('utf-8').strip()) for para in nodes])
所以,对于每个 <p1>
标签,我想到达 <p2>
内的 <p3>
个标签。然后我只想要 <p3>
标签直到标签有像 ABC
这样的文本。但是,如果我 运行 上面的代码,我得到
1 2 ABC 3 4 5 ABC 6 7 8 ABC 9
期望的输出是
1 2 4 5 7 8 10 11
此外,如果我进行此更改
nodes = root.xpath("./doc//p1/p2/p3[contains(text(),'ABC')]")
我得到
ABC ABC ABC ABC
所以看起来第二种方法能够根据 xpath 从整个文档中获取所有 <p3>
节点,这很好。为什么我的第一个查询不起作用?
如何获得所需的输出?
找到包含 ABC
的 p3
后,您无需爬上树 - 只需使用 preceding-sibling
前往 "sideways":
./doc//p1/p2/p3[contains(text(),'ABC')]/preceding-sibling::p3
打印 1 2 4 5 7 8 10 11
.