改进XPath查询以正确区分文本节点

时间:2018-09-02 19:06:43

标签: xpath domxpath xpath-1.0 xpathquery

过去,我广泛使用XPath。目前,我正面临一个无法解决的问题。

约束

  • 纯XPath 1.0
  • 没有辅助功能(例如,没有“ concat()”)

HTML标记

<span class="container">
    Peter: Lorem Impsum
    <i class="divider" role="img" aria-label="|"></i>
    Paul Smith: Foo Bar BAZ
    <i class="divider" role="img" aria-label="|"></i>
    Mary: One Two Three
</span>

挑战

我想提取三个连贯的字符串:

  • Peter:Lorem Impsum
  • Paul Smith:Foo Bar BAZ
  • 玛丽:一二三

XPath

经过数小时的研究,以下XPath查询是我提出的最好的查询:

XPath-query 1

//span[contains(@class, "container")]

=> Peter: Lorem ImpsumPaul Smith: Foo Bar BAZMary: One Two Three

XPath-query 2

//span[contains(@class, "container")]//text()

Peter: Lorem Impsum Paul Smith: Foo Bar BAZ Mary: One Two Three

问题

尽管之后可以使用(PHP)字符串函数对结果字符串进行后处理,但我无法将其分成正确的三个块:我需要一个XPath查询,该查询使我能够区分正确的文本节点

是否可以在文本节点之间集成一些“人工分隔符”?

1 个答案:

答案 0 :(得分:1)

您对XPath 1.0期望太多。 XPath 1.0本身可以在这里帮助您选择

  1. 字符串,或
  2. 一组文本节点

然后,您必须在XPath之外完成处理(如Mads在评论中所建议)。

要了解您遇到的限制,第一个XPath

//span[contains(@class, "container")]

选择一个span个元素的节点集。 XPath 1.0运行所在的环境向您显示了文档中单个此类节点的 string值(有些变化):

Peter: Lorem ImpsumPaul Smith: Foo Bar BAZMary: One Two Three

但请注意:您的XPath选择的是span元素的节点集,而不是此处的字符串。

您的第二个XPath,

//span[contains(@class, "container")]//text()

选择一个text()个节点的节点集。 XPath 1.0运行的环境正在显示每个选定的text()节点的 string值

如果可以使用XPath 2.0,则可以直接在XPath中选择字符串的序列

//span[contains(@class, "container")]/text()/string()

或者您可以加入他们,

string-join(//span[contains(@class, "container")]/text(), "|")

直接获得

Peter: Lorem Impsum
|
Paul Smith: Foo Bar BAZ
|
Mary: One Two Three

string-join(//span[contains(@class, "container")]/text()/normalize-space(), "|")

获取

Peter: Lorem Impsum|Paul Smith: Foo Bar BAZ|Mary: One Two Three