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() для чтения атрибутов элементов.