PHP XPath - проблемы с чтением атрибутов узла с "оценивать"

Мне нужно прочитать атрибуты «id», но я получаю либо пустые строки, либо строку, содержащую «один», в зависимости от используемого выражения XPath.

Я намеренно использую метод «запроса», чтобы получить DOMNodeList с узлами, тогда я хочу работать с ними. Пожалуйста, проверьте следующий код:

<?php
$xml = '
    <ROOT>
        <MEMBER id = "one" />
        <MEMBER id = "two" />
    </ROOT>
';


$dom = new \DOMDocument('1.0', 'utf-8');
$dom->loadXML($xml);
$xpath = new DOMXpath($dom);

$members = $xpath->query('/ROOT/MEMBER');  // object of class DOMNodeList

foreach ($members as $member) {
    echo($dom->saveXML($member));  // displays <MEMBER id = "one"/> and <MEMBER id = "two"/> as expected
    $id = $xpath->evaluate('string(/MEMBER/@id)', $member);   // let's read the id attribute
    var_dump($id);  // returns string(0) "" in both cases  - how come?
    $id = $xpath->evaluate('string(//MEMBER/@id)', $member);   // should make no difference
    var_dump($id);  // string(3) "one" in both cases
}

в foreach вы уже находитесь в контексте MEMBER, поэтому вместо /MEMBER/@id используйте только @id, надеюсь, вы получите желаемый результат.

Amrendra Kumar 18.12.2018 14:54

Ага, это работает. Но MEMBER является корневым узлом, поэтому /MEMBER/@id тоже должен работать. Я все еще в замешательстве ...

Pontiac_CZ 18.12.2018 15:24

В вашем входном корневом XML-узле - ROOT

Amrendra Kumar 18.12.2018 15:35

В $ dom это ROOT, в $ member корневой узел - MEMBER.

Pontiac_CZ 18.12.2018 16:38

если вы используете /MEMBER/@id, это означает, что ваш текущий контекст должен быть похож на <MEMBER><MEMBER id = "one" /><MEMBER id = "two" /></MEMBER>

Amrendra Kumar 18.12.2018 17:03

??? Я не понимаю. Я не уверен, что вы имеете в виду под текущим контекстом. Вернемся к DOMNodeList. Каждый запуск foreach создает экземпляр DOMElement ($ member). Метод saveXML () выводит <MEMBER id = "one"/> для первого $ member. Итак, <MEMBER> - корневой узел $ member, верно? И согласно w3schools.com/xml/xpath_syntax.asp я должен иметь возможность использовать выражение /MEMBER/@id для получения атрибута корневого узла.

Pontiac_CZ 18.12.2018 17:26
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
6
27
1

Ответы 1

в foreach вы уже находитесь в контексте MEMBER, поэтому вместо /MEMBER/@id используйте только @id, надеюсь, вы получите желаемый результат.

На самом деле в foreach ($members as $member) есть два <MEMBER id = "one" />, и <MEMBER id = "two" /> будут контекстом, поэтому вы уже находитесь в элементе MEMBER, вам просто нужно выбрать @id из текущего контекста.

Если вы напечатаете $member, тогда вы будете знать, что хранится в этом контексте, тогда картина будет ясной.

Примите ответ, если он вам подходит.

Другие вопросы по теме