xml_parse_into_struct()
Функция xml_parse_into_struct() разбирает XML-данные в многомерный массив PHP. Узнайте о параметрах, возвращаемых массивах и примерах.
Функция xml_parse_into_struct() — это встроенная функция PHP, которая разбирает XML-данные в многомерный массив. Она относится к расширению XML Parser и предоставляет низкоуровневое SAX-представление документа: вместо навигируемого дерева объектов она преобразует XML в плоский список «событий» (открывающий тег, символьные данные, закрывающий тег), по которому можно итерироваться.
На этой странице описано, что возвращает функция, её полная сигнатура, как читать два выходных массива ($values и $index), а также два полных, готовых к запуску примера.
Убедитесь, что расширение xml включено в конфигурации php.ini перед использованием этой функции (оно включено и активировано по умолчанию в большинстве сборок PHP).
Когда использовать
xml_parse_into_struct() полезна, когда нужно обойти каждый элемент XML-документа в порядке следования — например, для преобразования XML в другой формат, выравнивания вложенных данных или анализа структуры файла.
Для большинства повседневных задач объектно-ориентированный API SimpleXML (simplexml_load_string() / simplexml_load_file()) проще в чтении. Используйте xml_parse_into_struct(), когда вам нужен именно линейный, событийный массив, который она создаёт.
Синтаксис
Сигнатура функции xml_parse_into_struct() выглядит следующим образом:
xml_parse_into_struct($parser, $data, &$values, &$index): int| Параметр | Описание |
|---|---|
$parser | Ресурс XML-парсера, возвращённый функцией xml_parser_create(). |
$data | Строка, содержащая XML для разбора. |
&$values | Передаётся по ссылке. Заполняется одним ассоциативным массивом для каждого события разбора. |
&$index | Передаётся по ссылке. Сопоставляет каждое имя тега с позициями его событий внутри $values, чтобы можно было перейти прямо к нужному элементу. |
Возвращает 0 при ошибке и ненулевое значение при успехе.
Структура $values
Каждая запись в $values описывает одно событие и содержит следующие ключи:
tag— имя элемента.type— одно из значений:open(открывающий тег с дочерними элементами),close(закрывающий тег),complete(самодостаточный элемент) илиcdata(символьные данные между тегами).level— глубина вложенности, начиная с1.value— текстовое содержимое, если присутствует.attributes— ассоциативный массив атрибутов элемента, если присутствуют.
Примеры использования
Рассмотрим несколько практических примеров использования xml_parse_into_struct() в PHP. В обоих примерах используется следующий документ data.xml:
<?xml version="1.0"?>
<library>
<book>
<title>PHP Basics</title>
<author>Jane Doe</author>
</book>
<book>
<title>XML Parsing</title>
<author>John Smith</author>
</book>
</library>Пример 1: Разбор XML-данных в структурированный массив
Читаем файл, разбираем его в $values и $index и сообщаем о любой ошибке:
$xml_parser = xml_parser_create();
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0);
$xml_data = file_get_contents("data.xml");
$values = array();
$index = array();
if (!xml_parse_into_struct($xml_parser, $xml_data, $values, $index)) {
$error_message = xml_error_string(xml_get_error_code($xml_parser));
$error_line = xml_get_current_line_number($xml_parser);
echo "XML Parsing Error: $error_message at line $error_line";
}
xml_parser_free($xml_parser);Этот код создаёт XML-парсер с помощью xml_parser_create() и отключает сворачивание регистра (через xml_parser_set_option()), чтобы имена тегов сохраняли исходный регистр. Затем читает XML-файл в $xml_data, инициализирует пустые массивы $values и $index, после чего вызывает xml_parse_into_struct() для их заполнения. При ошибке разбора получает код с помощью xml_get_error_code(), преобразует его в сообщение через xml_error_string() и выводит номер строки. Наконец освобождает парсер с помощью xml_parser_free().
После успешного разбора $index позволяет перейти прямо ко всем вхождениям тега. Для приведённого документа он выглядит следующим образом:
// $index
[
"library" => [0, 7, 14, 15],
"book" => [1, 3, 5, 6, 8, 10, 12, 13],
"title" => [2, 9],
"author" => [4, 11],
]Каждое число — это смещение в $values. Таким образом, $index["title"] указывает, что два события <title> находятся на позициях 2 и 9. Это можно использовать для прямого извлечения значений:
foreach ($index["title"] as $i) {
echo "Title: " . $values[$i]["value"] . "\n";
}Результат:
Title: PHP Basics
Title: XML ParsingПример 2: Анализ структуры XML-файла
Чтобы проверить форму документа, итерируемся по $values и реагируем на type каждого события. Настройка та же, что в Примере 1; новая часть — цикл:
$xml_parser = xml_parser_create();
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0);
$xml_data = file_get_contents("data.xml");
$values = array();
$index = array();
if (!xml_parse_into_struct($xml_parser, $xml_data, $values, $index)) {
$error_message = xml_error_string(xml_get_error_code($xml_parser));
$error_line = xml_get_current_line_number($xml_parser);
echo "XML Parsing Error: $error_message at line $error_line";
}
xml_parser_free($xml_parser);
foreach ($values as $value) {
if ($value["type"] == "open") {
echo "Start element: " . $value["tag"] . "<br/>";
} else if ($value["type"] == "close") {
echo "End element: " . $value["tag"] . "<br/>";
}
}Этот цикл проверяет type каждого события: "open" выводит открывающий тег, "close" — закрывающий. Для примера документа вывод будет следующим:
Start element: library
Start element: book
End element: book
Start element: book
End element: book
End element: libraryОбратите внимание, что <title> и <author> здесь не появляются: поскольку они содержат только текст, они поступают как события complete, а не отдельные пары open/close. Добавьте обработку case "complete" (или проверку $value["value"]), если вам нужно их содержимое.
Заключение
Функция PHP xml_parse_into_struct() преобразует XML в линейный массив событий разбора, предоставляя низкоуровневый, SAX-подобный способ чтения документа. Ключ к эффективному использованию — понимание двух выходных массивов: $values содержит упорядоченные события (каждое с ключами tag, type, level, value и attributes), а $index сопоставляет имена тегов с их позициями, чтобы можно было обратиться к любому элементу напрямую.
Для навигации по структурированному XML в повседневном коде предпочтительнее SimpleXML; для работы с потоком событий, показанной здесь, xml_parse_into_struct() (или низкоуровневый xml_parse() с обработчиками) является правильным инструментом.