Как получить все значения узлов из канала

У меня есть следующий канал:

$result = apiCall('somevalue', 'somevalue', array('somevalue' => $some_string));

который находится в формате JSON. Я могу очень легко превратить его в XML с

$xml = simplexml_load_string($result);

Канал xml выглядит следующим образом:

<?xml version="1.0" encoding="ISO-8859-15"?>
    <response>
        <status>success</status>
        <code>200</code>
        <message>
            <a>
                <g>val1</g>
                <b>val2</b>
                <c>val3</c>
            </a>
            <d>
                <e>val4</e>
                <f>val5</f>
            </d>
        </message>
    </response>

Существует ли простой и быстрый способ получить все значения узлов (т.е. val1, val2, val3, val4, val5 и т. Д.)?

2 ответа

Решение

Я написал что-то, что я думаю, будет работать:

<?php

$xml = <<<EOD
<?xml version="1.0" encoding="ISO-8859-15"?>
<response>
    <status>success</status>
    <code>200</code>
    <message>
        <a>
            <g>val1</g>
            <b>val2</b>
            <c>val3</c>
        </a>
        <d>
            <e>val4</e>
            <f>val5</f>
        </d>
    </message>
</response>
EOD;

$output = array();
$test = simplexml_load_string($xml);
$result = $test->xpath('message//*[not(*)]');
while(list(, $node) = each($result)) {
    array_push($output, (string) $node);
}

var_dump($output);

?>

Я не тестировал его на многих вещах (атрибутах), но на предоставленном входе он дает ожидаемый результат. Это похоже на то, что вы можете видеть выражение xpath, которое извлекает любого потомка message узел.

Конечно, поскольку есть также узлы с еще большим количеством дочерних узлов (например, aа также d) нам нужно отфильтровать их. Так что последняя часть, содержащая not(*) означает, что будут выбраны только те дочерние элементы, у которых нет дочерних дочерних элементов.

Я не эксперт XPATH, поэтому, возможно, есть более быстрые способы достижения этого, но я думаю, что это подойдет.

Я пришел к аналогичному выводу, как Dimitri M, он основан на предыдущих вопросах и ответах. Как выбрать все конечные узлы, используя выражение XPath?,

Листовые узлы - это самые внешние узлы, которые вы ищете, здесь text() узлы в вашем случае.

$nodeValues = array_map(
    'trim',
    simplexml_load_string($xml)->xpath('message//*[not(*)]/text()')
);

При условии $xml ваш ввод XML, $nodeValues затем массив всех тех строк, которые представляют значения узлов, которые вы ищете. Примерное:

Array
(
    [0] => val1
    [1] => val2
    [2] => val3
    [3] => val4
    [4] => val5
)
Другие вопросы по тегам