W3docs

getchildren()

SimpleXML — расширение PHP с удобным API для работы с XML-документами. Функция SimpleXMLElement::children() позволяет получать дочерние элементы узла.

SimpleXMLElement::children()

SimpleXML — это расширение PHP, предоставляющее простой API для разбора и обработки XML-документов. Среди его методов SimpleXMLElement::children() позволяет получить непосредственные дочерние элементы узла в виде объектов SimpleXMLElement, чтобы можно было перебирать их в цикле. В этом руководстве объясняется, что возвращает метод, как он работает с пространствами имён и как применять его на реальных документах.

Устаревший псевдоним getChildren() относится к интерфейсу RecursiveIterator, который реализует SimpleXMLElement. В повседневном коде вы вызываете children() напрямую; именно этот метод рассматривается на данной странице.

Что возвращает SimpleXMLElement::children()

children() возвращает объект SimpleXMLElement, по которому можно итерироваться с помощью foreach для доступа к прямым потомкам текущего узла — метод не выполняет рекурсивный обход внуков автоматически. Он принимает необязательный аргумент $namespace для ограничения результата одним XML-пространством имён, что необходимо, когда документ сочетает несколько словарей (например, RSS и Dublin Core).

Синтаксис

public function children(?string $namespace = null, bool $isPrefix = false): ?SimpleXMLElement
  • $namespace — URI пространства имён (или, если $isPrefix равен true, префикс пространства имён). Когда значение равно null (по умолчанию), возвращаются дочерние элементы из текущего контекста пространства имён.
  • $isPrefix — установите в true, если передаёте префикс (например, "bk") вместо полного URI.

Примечание о пространствах имён по умолчанию: когда XML использует пространство имён по умолчанию (объявлённое через xmlns="..." без префикса), необходимо передать URI этого пространства имён в children(), чтобы достичь вложенных элементов. Вызов children(null) на таком узле не вернёт ничего.

Базовый обход дерева

В примере ниже XML загружается из строки с помощью simplexml_load_string(), чтобы не требовать внешний файл, после чего дерево обходится с помощью вложенных вызовов children(). getName() возвращает имя тега каждого элемента:

<?php

$data = <<<XML
<?xml version="1.0"?>
<library>
  <book>
    <title>The PHP Way</title>
    <author>Ada Byte</author>
  </book>
  <book>
    <title>XML in Depth</title>
    <author>Lee Markup</author>
  </book>
</library>
XML;

$xml = simplexml_load_string($data);

foreach ($xml->children() as $book) {
    echo $book->getName() . ":\n";          // "book"
    foreach ($book->children() as $field) {
        echo "  " . $field->getName() . " = " . $field . "\n";
    }
}

Вывод:

book:
  title = The PHP Way
  author = Ada Byte
book:
  title = XML in Depth
  author = Lee Markup

Внешний цикл проходит по каждому элементу <book>, а внутренний — по его непосредственным потомкам (<title>, <author>). Приведение дочернего элемента к строке (здесь через конкатенацию) возвращает его текстовое содержимое.

Фильтрация по пространству имён

Когда документ объявляет пространства имён, передайте URI в children(), чтобы выбрать только соответствующие элементы. getNamespaces(true) возвращает все пространства имён документа с ключами по префиксу, что позволяет динамически получить нужный URI:

<?php

$data = <<<XML
<?xml version="1.0"?>
<catalog xmlns:bk="http://example.com/books">
  <bk:book>
    <bk:title>Namespaced PHP</bk:title>
  </bk:book>
  <bk:book>
    <bk:title>Beyond SimpleXML</bk:title>
  </bk:book>
</catalog>
XML;

$xml = simplexml_load_string($data);
$ns  = $xml->getNamespaces(true);            // ['bk' => 'http://example.com/books']

foreach ($xml->children($ns['bk']) as $book) {
    echo $book->children($ns['bk'])->title . "\n";
}

Вывод:

Namespaced PHP
Beyond SimpleXML

Поскольку каждый <bk:book> и его <bk:title> находятся в пространстве имён bk, необходимо передавать соответствующий URI на каждом уровне для доступа к ним.

Частые ошибки

  • Метод не является рекурсивным. children() возвращает только прямых потомков. Чтобы обойти всё дерево, вызывайте его повторно внутри цикла (как показано выше) или используйте запрос XPath.
  • Отсутствие фильтра пространства имён приводит к пустому результату. Если цикл молча возвращает пустой результат для XML с пространствами имён, вероятно, вы забыли передать URI пространства имён.
  • Текст против элементов. Приводите элемент к (string) и обрезайте его с помощью trim(), если вам нужно только текстовое содержимое, особенно при работе с узлами смешанного содержимого.
  • Всегда проверяйте входные данные. При загрузке из файла или URL проверяйте на false и включайте обработку ошибок libxml, прежде чем доверять результату.

Заключение

SimpleXMLElement::children() — стандартный способ итерации по прямым дочерним элементам XML-узла в PHP. Комбинируя его с getName() для получения имён тегов, URI пространств имён для фильтрации и приведением к строке для текстового содержимого, можно чисто обходить вложенные документы. Для более широкого контекста см. обзор PHP SimpleXML и связанный метод attributes() для чтения атрибутов элементов.

Практика

Практика
Для чего используется функция getChildren() в PHP?
Для чего используется функция getChildren() в PHP?
Was this page helpful?