使用XPath在2个XPath节点之间获取文本1.通用解决方案,而不是特定情况

时间:2018-03-06 23:26:19

标签: php xpath domxpath

有没有办法在XPath 1的两个节点之间获取文本?

示例:我们希望在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没有,它就会停止。我能找到的唯一答案是使用XPath 2.0:

  

“假设您想要在两个h3之间的所有树深处建立节点   元素,不一定是兄弟姐妹“

来自https://stackoverflow.com/a/3838151/3628541

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

1.0中的等价物是什么?

1 个答案:

答案 0 :(得分:1)

您正在寻找$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())]

可能会有糟糕的表现。