PHP-запрос DOMXPath, похоже, игнорирует параметр contextnode - PullRequest
0 голосов
/ 09 июня 2018

Я пытаюсь разобрать некоторый HTML, но у меня есть некоторые проблемы с функцией запроса DOMXPath.Я хочу, чтобы мой код находил все div с классом «контейнер», а затем в каждом из них находил div с классом «name».На http://php.net/manual/en/domxpath.query.php я прочитал, что вы можете указать contextnode для функции запроса XPath для поиска только внутри 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 голосов
/ 10 июня 2018

Проблема в том, что когда вы начинаете использовать //, вы говорите, что это может быть любой узел, так как DOM имеет ссылки вверх и вниз по иерархии, это дает XPath свободный дождь для поиска чего-либо.

Если вместо этого вы используете

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

, вы ограничиваете поиск только потомками контекстного узла.

0 голосов
/ 09 июня 2018

Я не могу проверить это банкоматом, но вы можете добиться этого с помощью одного запроса XPath:

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

foreach ($persons as $person) {
    print_r($person->textContent);
    echo "<hr>";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...