Как перебрать элементы DOM в PHP? - PullRequest
31 голосов
/ 10 октября 2008

У меня есть файл XML, загруженный в документ DOM, Я хочу перебрать все теги 'foo', получая значения из каждого тега под ним. Я знаю, что могу получить значения через

$element = $dom->getElementsByTagName('foo')->item(0);
foreach($element->childNodes as $node){
    $data[$node->nodeName] = $node->nodeValue;
}

Однако то, что я пытаюсь сделать, это из XML, как,

<stuff>
  <foo>
    <bar></bar>
      <value/>
    <pub></pub>
  </foo>
  <foo>
    <bar></bar>
    <pub></pub>
  </foo>
  <foo>
    <bar></bar>
    <pub></pub>
  </foo>
  </stuff>

итерирует по каждому тегу foo , получает конкретный bar или pub и получает оттуда значения. Теперь, как мне перебрать foo , чтобы я мог получить доступ к определенным дочерним узлам по имени?

Ответы [ 4 ]

43 голосов
/ 10 октября 2008

Не проверено, но как насчет:

$elements = $dom->getElementsByTagName('foo');
$data = array();
foreach($elements as $node){
    foreach($node->childNodes as $child) {
        $data[] = array($child->nodeName => $child->nodeValue);
    }
}
4 голосов
/ 11 октября 2008

Обычно гораздо лучше использовать XPath для запроса документа, чем писать код, который зависит от знания структуры документа. Есть две причины. Во-первых, кода для тестирования и отладки намного меньше. Во-вторых, если структура документа изменяется, гораздо проще изменить запрос XPath, чем изменить набор кода.

Конечно, вы должны изучать XPath, но (большая часть) XPath не является ракетостроением.

DOM PHP использует метод xpath_eval для выполнения запросов XPath. Здесь задокументировано здесь , и в примечаниях пользователя есть несколько довольно хороших примеров.

2 голосов
/ 09 декабря 2008

Вот еще один (ленивый) способ сделать это.

$data[][$node->nodeName] = $node->nodeValue;
0 голосов
/ 24 января 2016

С FluidXML вы можете очень легко запрашивать и повторять XML.

$data = [];

$store_child = function($i, $fooChild) use (&$data) {
    $data[] = [ $fooChild->nodeName => $fooChild->nodeValue ];
};

fluidxml($dom)->query('//foo/*')->each($store_child);

https://github.com/servo-php/fluidxml

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