Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python lxml XPath:前面的关键字未给出预期结果_Python_Xml_Xpath_Xml Parsing_Lxml - Fatal编程技术网

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

Python lxml XPath:前面的关键字未给出预期结果,python,xml,xpath,xml-parsing,lxml,Python,Xml,Xpath,Xml Parsing,Lxml,我试图解析一个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&

我试图解析一个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])
期望输出为

1 2 4 5 7 8 10 11
还有,如果我做了这个改变

nodes = root.xpath("./doc//p1/p2/p3[contains(text(),'ABC')]")
我明白了

看起来第二种方法能够根据xpath从整个文档中获取所有
节点,这很好。为什么我的第一个查询不起作用


如何获得所需的输出?

一旦找到包含
ABC
p3
,您就不需要爬上树,只需使用以下工具“侧向”即可:


打印
1 2 4 5 7 8 10 11

顺便问一下,为什么要对XML数据使用
lxml.html
?为什么不
lxml.etree
?我想使用soupparser来利用Beauty soup的html解析器完美!谢谢:)顺便问一下,为什么只在前面一个/之前?@AbtPst我不确定,但我认为在前面的兄弟姐妹之前,
/
/
不会有任何区别。。谢谢因此,
-或self
部分将在此处获得相同的结果,因为没有
p3
子项,
/
子代
部分不会选择任何内容
nodes = root.xpath("./doc//p1/p2/p3[contains(text(),'ABC')]")
ABC ABC ABC ABC
./doc//p1/p2/p3[contains(text(),'ABC')]/preceding-sibling::p3