PHP DOMXPath查询似乎忽略了contextnode参数

时间:2018-06-09 20:09:08

标签: php html parsing xpath

我正在尝试解析一些HTML但是在DOMXPath查询功能方面存在一些问题。我希望我的代码能够找到所有带有类"容器"的div。而且他们每个人都找到了一个名为" name"的div。在http://php.net/manual/en/domxpath.query.php上我读到你可以为XPath查询函数指定contextnode以仅在certian节点内搜索,但在我的情况下,它似乎没有做任何事情。

这可能是因为$ person是DOMElement类型的对象,XPath查询接受DOMNode作为contextnode。但据我所知,DOMElement扩展了DOMNode,因此不应该成为问题。此外,我没有收到任何错误或警告。

我使用的是PHP 5.5.12版。

这是我的代码:

<pre>
<?php
$html = '
<div class="junk">...</div>
<div class="container">
    <div class="name">Kdksf</div>
    <div class="surname">Gskdl</div>
    <div class="junk">...</div>
</div>
<div class="container">
    <div>
        <div>
            <div class="name">Rada</div>
            <div class="surname">Ldsa</div>
        </div>
    </div>
    <div class="junk">...</div>
</div>
<div class="container">
    <div class="name">Sdfex</div>
    <div class="surname">Fdss</div>
    <div class="junk">...</div>
</div>
<div class="junk">...</div>
';

$doc = new DOMDocument();
libxml_use_internal_errors(true);
$doc->loadHTML($html);
$xpath = new DOMXPath($doc);
$persons = $xpath->query("//*[contains(@class, 'container')]");

foreach ($persons as $person) {
    $name = $xpath->query("//*[contains(@class, 'name')]", $person);

    print_r($name->item(0)->textContent);

    echo "<hr>";
}

?>

预期输出为:

Kdksf
Rada
Sdfex

但我明白了:

Kdksf
Kdksf
Kdksf

2 个答案:

答案 0 :(得分:0)

我无法测试它,但您可以使用一个XPath查询来实现此目的:

$persons = $xpath->query("//*[contains(@class, 'container')]//div[@class='name']");

foreach ($persons as $person) {
    print_r($person->textContent);
    echo "<hr>";
}

答案 1 :(得分:0)

问题在于,当你开始使用//时,你说它可以是任何节点,因为DOM在层次结构中有上下链接,它可以让XPath免费下雨找到任何东西。

如果您使用

$name = $xpath->query("descendant::*[contains(@class, 'name')]", $person);

您将搜索范围限制为上下文节点的后代。