Как получить и прочитать конкретные данные из XML в PHP? - PullRequest
0 голосов
/ 14 сентября 2018

Привет всем, у меня есть эта структура XML, и я хотел бы получить значение IdDocumento атрибутов

<pago10:Pagos>
    <pago10:Pago>
        <pago10:DoctoRelacionado IdDocumento="B670AD5D-8BA6-42CF-A0D0-1A403E042FBA" />
    </pago10:Pago>
    <pago10:Pago>
        <pago10:DoctoRelacionado IdDocumento="B670AD5D-8BA6-42CF-A0D0-1A403E042FBA" />
        <pago10:DoctoRelacionado IdDocumento="842b32ce-44c1-4b31-96b8-3a34569c698c" />
    </pago10:Pago>
</pago10:Pagos>

Я пробовал с этим следующим образом:

$xml = simplexml_load_file('complemento.xml');

$ns = $xml->getNamespaces(true);

$xml->registerXPathNamespace('p', $ns['pago10']);


if ($xml->xpath('//p:Pagos')) {

    foreach ($xml->xpath('//p:Pagos') as $pagos10) {

        foreach ($xml->xpath('//p:Pago') as $pago10) {

            foreach ($xml->xpath('//p:DoctoRelacionado') as $doc) {

                echo $doc['IdDocumento'] . '<br>';
            }

            echo "=========================================";
        }
    }
}

Но это отображает сразу 3 атрибута IdDocumento. Я надеялся напечатать первый атрибут IdDocumento и создать разделитель, а затем распечатать два других, как я могу узнать, какой IdDocumento принадлежит каждому pago10:Pago узлу?

Ожидаемый результат:

B670AD5D-8BA6-42CF-A0D0-1A403E042FB
====================================
B670AD5D-8BA6-42CF-A0D0-1A403E042FBA
842b32ce-44c1-4b31-96b8-3a34569c698c

Что я получаю:

B670AD5D-8BA6-42CF-A0D0-1A403E042FB
B670AD5D-8BA6-42CF-A0D0-1A403E042FBA
842b32ce-44c1-4b31-96b8-3a34569c698c
====================================
B670AD5D-8BA6-42CF-A0D0-1A403E042FB
B670AD5D-8BA6-42CF-A0D0-1A403E042FBA
842b32ce-44c1-4b31-96b8-3a34569c698c

Ответы [ 2 ]

0 голосов
/ 14 сентября 2018

Проблема с вашим xpath в том, что $xml->xpath('//p:DoctoRelacionado') получит все элементы с DoctoRelacionado, а не только те, которые находятся внутри текущего Pago.

Вместо этоготолько первый foreach должен использовать xpath, а остальные должны использовать что-то вроде children() метода SimpleXMLElement.

Чтобы исправить это, попробуйте переключить свои операторы foreach для следующего:

foreach ($xml->xpath('//p:Pagos') as $pagos10) {
    foreach ($pagos10->children() as $pago10) {
        foreach ($pago10->children() as $doc) {
            echo $doc['IdDocumento'] . '<br>';
        }
        echo "=========================================<br>";
    }
}
0 голосов
/ 14 сентября 2018

Одной из проблем было то, как вы всегда использовали $xml в качестве начальной точки для XPath, поэтому всегда возвращался к верхнему уровню документа, чтобы найти следующий слой элементов. В этом коде он использует элемент из предыдущего foreach() в качестве начальной точки.

Также обратите внимание, что в нем используется нисходящая ось ('descendant::), поэтому используются только те элементы, которые находятся под начальной точкой.

$ns = $xml->getNamespaces(true);

$xml->registerXPathNamespace('pago10', $ns['pago10']);

if ($xml->xpath('//pago10:Pagos')) {
    foreach ($xml->xpath('//pago10:Pagos') as $pagos10) {
        foreach ($pagos10->xpath('descendant::pago10:Pago') as $pago10) {
            foreach ($pago10->xpath('descendant::pago10:DoctoRelacionado') as $doc) {

                echo $doc['IdDocumento'] . '<br>';
            }

            echo "=========================================".PHP_EOL;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...