Get text between 2 XPath nodes using XPath 1. 通用解决方案,不是特殊情况

Get text between 2 XPath nodes using XPath 1. Generic solution, not a particular case

有没有办法使用 XPath 1 获取 2 个节点之间的文本?

示例:我们想要获取 F 和 D 之间的文本,预期结果为 "G"

    $html = ''.
        '<html>'.
        '<body>'.
        '<a>A</a>'.
        '<b>B
            <c>C
                <F>F</F>
            </c>
            <G>G</G>
        </b>'.
        '<d>D
            <e>E</e>
        </d>'.
        '</body>'.
        '</html>';

这里是查询:

$dom = new \DOMDocument();
@$dom->loadHTML($html);
$xpath = new \DOMXPath($dom);
$a = '/html/body/b/c/f';
$b = '/html/body/d';
$nodesBetween = getNodesBetween($a,$b, $xpath);

最后函数:

public function getNodesBetween($a, $b, $domxpath) {
        $query = $a."/following::text()[. = ".$b."/preceding::text()]";
        $elements = $domxpath->query($query);
        $inside = '';
        foreach ($elements as $element) {
            $inside .= $element->nodeValue;
        }
        dd($inside);
}

如果我尝试从 A 搜索到 D,它可以正常工作并且输出是 "B C F G"。如果我在 F 和 D 之间搜索,它会返回一个空字符串。它似乎正在寻找兄弟姐妹,并且由于 F 有 none,它停止了。我能找到的唯一答案是 XPath 2.0:

"assuming you want nodes at all tree depths between the two h3 elements, which would not necessarily be siblings"

来自

/path/to/first/h3/following::node()[. << /path/to/second/h3]

1.0 中的等价物是什么?

您正在寻找 $A/following::node()$B/preceding::node() 的交集。

在 XPath 1.0 中,$X 和 $Y 的交集由 $X[count(.|$Y)=count($Y)] 给出。

所以这给了你

$A/following::node()[count(.|$B/preceding::node())=count($B/preceding::node())]

这很可能会产生非常糟糕的性能。