Python lxml XPath:前面的关键字没有给出预期的结果



我正试图按照以下解析一个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>节点,这很好。为什么我的第一个查询不起作用?

如何获得所需的输出?

一旦找到包含ABCp3,就不需要爬上树,只需使用preceding-sibling:"侧向"即可

./doc//p1/p2/p3[contains(text(),'ABC')]/preceding-sibling::p3

打印1 2 4 5 7 8 10 11

最新更新