Xpath 不想选择我的标签

Xpath doesn't want to select my tags

本文关键字:我的 标签 选择我 选择 不想 Xpath      更新时间:2023-09-26

>我有以下包含地址的HTML代码:

<html>
<body>
    <div>
        <h2>Address</h2>
        <p>
            Rotes Rathaus<br />
            Rathausstrasse<br />
            10178 Berlin<br />
            Germany<br />
        </p>
    </div>
</body>
</html>

我试图找到包装地址的段落节点(在我的例子中:<p>标签),我所拥有的只是地址的一组部分(例如:"市政厅"、"柏林"、"10178")。

我正在使用以下 XPath 选择器查询 dom:

//*[contains(text(),'Rathaus')]

这很好用,并且返回了

节点。但是,当我根据邮政编码查找时,我没有得到任何匹配项:

//*[contains(text(),'10178')]

我需要做什么才能解决这个问题?请注意,地址的位置可以在页面上的任何位置。

此致敬意尼古拉斯

解决方案

//*[text()[contains(.,'10178')]]

结果将选择p元素。这意味着

在文档中的任意位置查找任何元素节点,但前提是至少有一个字符串值包含"10178"的子文本节点。

另一方面,您的原始表达:

//*[contains(text(),'10178')]

方法:

在文档中的任意位置查找任何元素节点,但前提是其第一个子文本节点包含字符串"10178"。

解释

由于函数在 XPath 1.0 中的工作方式,您会对结果感到惊讶。像 contains() 这样的函数需要单个节点作为第一个参数。如果给它一组节点,它只会处理第一个节点,而忽略其余节点。

您需要了解的另一件事是,由子元素分隔的文本最终位于单独的文本节点中。因此,由于中间br元素,P的文本内容实际上被切割成几个文本节点。

您可以通过计算类似

//p/node()           |  Find `p` elements anywhere in the document and return all nodes
                        that are their children, regardless of the type of node.

在您显示的文档上,它将返回(以 ------- 分隔的各个结果):

            Rotes Rathaus
-----------------------
<br/>
-----------------------
            Rathausstrasse
-----------------------
<br/>
-----------------------
            10178 Berlin
-----------------------
<br/>
-----------------------
            Germany
-----------------------
<br/>
-----------------------

如您所见,只要两者之间存在brp的文本内容就会存储在单独的文本节点中。此时,您应该意识到,如果"10178"恰好在第一个文本节点而不是第三个文本节点中,您的原始表达式将起作用。也许你可以猜到//p/text()[3]会产生什么结果?


最后一个提示:这在 XPath 2.0 中发生了变化,其中多个项目是真正的节点序列,函数将依次处理每个节点。