W3docs

PHP XML Парсеры: Исчерпывающее руководство

Узнайте, как разбирать XML в PHP с помощью SimpleXML, XMLReader и DOM. Примеры, обработка ошибок и выбор парсера.

XML (eXtensible Markup Language) — широко используемый формат для обмена структурированными данными между приложениями, веб-сервисами и платформами. Поскольку многие API, файлы конфигурации и ленты по-прежнему используют его, умение читать XML в PHP является практически полезным навыком. Это руководство описывает три встроенных XML-парсера, поставляемых с PHP — SimpleXML, XMLReader и DOM — показывает рабочие примеры для каждого и помогает выбрать подходящий для вашей задачи.

Что такое XML-парсер в PHP?

XML парсер — это библиотека, которая читает XML-документ, проверяет его корректность и предоставляет вашему коду структурированный доступ к его элементам, атрибутам и тексту. PHP поставляется с тремя встроенными парсерами, все они построены на одном и том же базовом движке libxml:

  • SimpleXML — древовидный парсер, загружающий весь документ в удобный для использования объект.
  • DOM — древовидный парсер, следующий стандарту W3C Document Object Model, с более богатым API для навигации и редактирования.
  • XMLReader — потоковый парсер на основе курсора, читающий по одному узлу за раз без загрузки всего документа в память.

«Древовидный» означает, что весь документ хранится в памяти в виде навигируемой структуры — простой в использовании, но требовательный к памяти для больших файлов. «Потоковый» (также называемый pull-парсинг) означает, что парсер проходит по документу узел за узлом, что позволяет экономить память при работе с большими файлами.

Все примеры ниже используют один и тот же образец документа, встроенного в виде строки, так что вы можете запустить их как есть:

$xmlString = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<library>
  <book>
    <title>PHP for Beginners</title>
    <author>Jane Doe</author>
    <year>2021</year>
  </book>
  <book>
    <title>Advanced PHP</title>
    <author>John Smith</author>
    <year>2023</year>
  </book>
</library>
XML;

SimpleXML

SimpleXML предоставляет самый быстрый способ чтения XML. Вы загружаете документ в объект SimpleXMLElement и затем обращаетесь к его данным через обычные свойства объекта — $xml->book[0]->title вместо каких-либо вызовов методов. Это идеально подходит для небольших и средних документов с известной структурой.

Используйте simplexml_load_string() для XML, уже имеющегося в виде строки, или simplexml_load_file() для чтения непосредственно из файла или URL.

$xml = simplexml_load_string($xmlString);

// Access a single value by position
echo $xml->book[0]->title . "\n";

// Loop over every <book> element
foreach ($xml->book as $book) {
    echo "{$book->title} by {$book->author} ({$book->year})\n";
}

Вывод:

PHP for Beginners
PHP for Beginners by Jane Doe (2021)
Advanced PHP by John Smith (2023)

Обратите внимание, что значения элементов являются объектами SimpleXMLElement, а не обычными строками. Конкатенация или echo автоматически приводят их к тексту, но используйте приведение (string), когда вам нужна настоящая строка. Смотрите PHP SimpleXML для более глубокого изучения, включая чтение атрибутов и пространств имён.

XMLReader

XMLReader — это потоковый парсер с однонаправленным чтением. Вместо построения дерева он проходит по документу по одному узлу за раз, поэтому потребление памяти остаётся низким независимо от размера файла. Это делает его правильным выбором для больших лент или экспортов, где загрузка всего сразу привела бы к исчерпанию памяти.

Вызывайте read() для перехода к следующему узлу, затем проверяйте nodeType и name, чтобы решить, что делать. Используйте open() для чтения из файла или URL, или XML() для чтения из строки.

$reader = new XMLReader();
$reader->XML($xmlString);

while ($reader->read()) {
    if ($reader->nodeType === XMLReader::ELEMENT && $reader->name === 'title') {
        echo $reader->readString() . "\n";
    }
}
$reader->close();

Вывод:

PHP for Beginners
Advanced PHP

Компромисс — удобство: поскольку XMLReader всегда хранит только один узел, нет произвольного доступа — вы не можете вернуться назад или запрашивать произвольные элементы, как в дереве. Распространённый паттерн — стримить до нужного элемента, а затем передать это поддерево в SimpleXML или DOM с помощью expand().

DOM

Расширение DOM реализует стандарт W3C Document Object Model. Как и SimpleXML, оно загружает весь документ в дерево, но предоставляет более полный API для навигации по узлам, запросов с XPath и создания или изменения элементов. Выбирайте DOM, когда вам нужно записывать или реструктурировать XML, а не только читать.

Загружайте XML с помощью loadXML() (из строки) или load() (из файла), затем обходите дерево с помощью таких методов, как getElementsByTagName().

$dom = new DOMDocument();
$dom->loadXML($xmlString);

$titles = $dom->getElementsByTagName('title');
foreach ($titles as $title) {
    echo $title->nodeValue . "\n";
}

Вывод:

PHP for Beginners
Advanced PHP

getElementsByTagName() возвращает DOMNodeList, по которому можно итерироваться или обращаться по индексу с помощью ->item(0). Для более сложных запросов можно сочетать DOMDocument с DOMXPath. Смотрите PHP XML DOM для полного описания API.

Обработка ошибок парсинга

По умолчанию некорректный XML вызывает предупреждения PHP, с которыми трудно работать программно. Вызовите libxml_use_internal_errors(true), чтобы подавить эти предупреждения и вместо этого собирать структурированные объекты ошибок с помощью libxml_get_errors(). Все три парсера разделяют этот механизм ошибок libxml.

libxml_use_internal_errors(true);

$badXml = '<library><book><title>Unclosed</book></library>';
$xml = simplexml_load_string($badXml);

if ($xml === false) {
    echo "Failed to parse XML:\n";
    foreach (libxml_get_errors() as $error) {
        echo trim($error->message) . "\n";
    }
    libxml_clear_errors();
}

Вывод:

Failed to parse XML:
Opening and ending tag mismatch: title line 1 and book
Opening and ending tag mismatch: book line 1 and library
Premature end of data in tag library line 1

Всегда проверяйте возвращаемое значение функции загрузки (false при ошибке) перед использованием результата. Подробнее об этих вспомогательных функциях смотрите в PHP libxml.

Выбор подходящего XML-парсера PHP

ПарсерМодельПамятьЛучше всего подходит для
SimpleXMLДеревоВысокаяБыстрое чтение небольших/средних документов
DOMДеревоВысокаяРедактирование, запросы XPath, построение XML
XMLReaderПотоковаяНизкаяБольшие документы, читаемые однократно сверху вниз

Коротко:

  • Выбирайте SimpleXML, когда вам просто нужно читать известный XML умеренного размера с минимальным кодом.
  • Выбирайте DOM, когда нужно изменять документы, выполнять XPath-запросы или генерировать XML.
  • Выбирайте XMLReader, когда документ достаточно велик, что загрузка его целиком в память представляет проблему.

Заключение

PHP предоставляет три встроенных XML-парсера, каждый из которых подходит для разных задач: SimpleXML для быстрого и простого чтения, DOM для полной манипуляции, и XMLReader для экономной по памяти потоковой обработки больших файлов. Подбирайте парсер в соответствии с размером документа и тем, нужно ли вам только читать или также писать, оборачивайте загрузку в обработку ошибок libxml, и вы сможете надёжно разбирать XML в любом PHP-проекте.

Для дальнейшего изучения ознакомьтесь с PHP SimpleXML parser, PHP XML parser (Expat) и PHP XML DOM.

Практика

Практика
Какие из перечисленных являются встроенными XML-парсерами PHP, рассмотренными в этом руководстве?
Какие из перечисленных являются встроенными XML-парсерами PHP, рассмотренными в этом руководстве?
Was this page helpful?