XML в PHP от простого чтения до сложных преобразований

Раздел: Разработка на PHP -> Работа с форматами данных

Основные подходы к обработке XML в PHP

Как загрузить и разобрать XML-документ с минимальным кодом?

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

Пример: загрузка XML из строки


$xmlString = '<book><title>PHP для начинающих</title><author>Иван Петров</author></book>';
$xml = simplexml_load_string($xmlString);
echo $xml->title; // PHP для начинающих

Xml файл php (работа с xml в php)

Пример: загрузка из файла


$xml = simplexml_load_file('books.xml');
foreach ($xml->book as $book) {
    echo $book->title . ' - ' . $book->author . "\n";
}

Excel файлы php (работа с excel-файлами в php)

Доступ к атрибутам


$xml = simplexml_load_string('<book id="123"><title>PHP</title></book>');
echo $xml['id']; // 123

Изменение и сохранение


$xml->title = 'Новое название';
$xml->addChild('price', 1000);
file_put_contents('books.xml', $xml->asXML());

Проблема: при загрузке некорректного XML SimpleXML генерирует предупреждения (warning) и возвращает false. Решение: проверять результат и подавлять ошибки с помощью libxml_use_internal_errors(true).


libxml_use_internal_errors(true);
$xml = simplexml_load_file('broken.xml');
if ($xml === false) {
    foreach (libxml_get_errors() as $error) {
        echo $error->message;
    }
    libxml_clear_errors();
}

Как управлять XML с полным контролем над структурой?

Расширение DOMDocument предоставляет полную реализацию DOM. Подходит для создания сложных документов, вставки узлов в произвольные позиции, работы с пространствами имён и валидацией.

Пример: создание XML с нуля


$dom = new DOMDocument('1.0', 'UTF-8');
$root = $dom->createElement('catalog');
$dom->appendChild($root);
$book = $dom->createElement('book');
$book->setAttribute('id', '1');
$root->appendChild($book);
$title = $dom->createElement('title', 'PHP и MySQL');
$book->appendChild($title);
echo $dom->saveXML();

Проблема: DOMDocument требует явного управления памятью при больших документах, но в целом стабилен. Ошибка: попытка использовать специальные символы в тексте узла - они должны быть экранированы. DOM делает это автоматически при использовании метода createTextNode.

Как обработать очень большой XML-файл без загрузки в память?

Расширение XMLReader позволяет читать документ потоково, узел за узлом. Идеально для файлов размером в гигабайты.

Пример: чтение большого RSS-канала


$reader = new XMLReader();
$reader->open('big.xml');
while ($reader->read()) {
    if ($reader->nodeType == XMLREADER::ELEMENT && $reader->localName == 'item') {
        $item = $reader->readOuterXml();
        // обработка одного элемента
    }
}
$reader->close();

Как создать большой XML-файл, не храня весь документ в памяти?

XMLWriter пишет XML потоково. Полезно при экспорте больших наборов данных.

Пример: потоковая запись


$writer = new XMLWriter();
$writer->openURI('output.xml');
$writer->startDocument('1.0', 'UTF-8');
$writer->startElement('catalog');
for ($i = 0; $i < 1000; $i++) {
    $writer->startElement('book');
    $writer->writeAttribute('id', $i);
    $writer->writeElement('title', 'Книга ' . $i);
    $writer->endElement();
}
$writer->endElement();
$writer->endDocument();
$writer->flush();

Как выполнять сложные запросы к XML (выборка по условию)?

XPath поддерживается как SimpleXML, так и DOM. Позволяет искать узлы по пути, условиям и атрибутам.

Пример: поиск всех книг с ценой > 500


$xml = simplexml_load_file('catalog.xml');
$books = $xml->xpath("//book[price > 500]");
foreach ($books as $book) {
    echo $book->title;
}

Цели и случаи использования каждого подхода

  • SimpleXML - для быстрого чтения/записи, когда структура известна и не требуется тонкое управление.
  • DOMDocument - для полного контроля над документом, создания сложных структур, валидации.
  • XMLReader - для потокового чтения очень больших файлов (десятки мегабайт и выше).
  • XMLWriter - для потоковой записи больших файлов без хранения всего содержимого в памяти.
  • XPath - для гибкой выборки данных внутри документа.

Расширенные примеры работы с XML в PHP

Пример 1: преобразование XML в ассоциативный массив с помощью SimpleXML и рекурсии

Пример

$xml = simplexml_load_string('<users><user id="1"><name>Анна</name><email>anna@example.com</email></user><user id="2"><name>Борис</name><email>boris@example.com</email></user></users>');

function xmlToArray(SimpleXMLElement $xml) {
    $result = [];
    foreach ($xml->children() as $key => $child) {
        $attrs = [];
        foreach ($child->attributes() as $attrKey => $attrVal) {
            $attrs['@' . $attrKey] = (string)$attrVal;
        }
        $children = $child->count() ? xmlToArray($child) : (string)$child;
        $result[] = $attrs ? array_merge(['@attributes' => $attrs], ['value' => $children]) : $children;
    }
    return $result;
}

$array = xmlToArray($xml);
print_r($array);
Array
(
    [0] => Array
        (
            [@attributes] => Array
                (
                    [@id] => 1
                )
            [value] => Array
                (
                    [name] => Анна
                    [email] => anna@example.com
                )
        )
    [1] => Array
        (
            [@attributes] => Array
                (
                    [@id] => 2
                )
            [value] => Array
                (
                    [name] => Борис
                    [email] => boris@example.com
                )
        )
)

Пример 2: использование DOMDocument для модификации существующего XML с удалением узлов

Пример

$dom = new DOMDocument();
$dom->load('catalog.xml');
$xpath = new DOMXPath($dom);
// Удаляем все книги с ценой меньше 100
$books = $xpath->query("//book[price < 100]");
foreach ($books as $book) {
    $book->parentNode->removeChild($book);
}
$dom->save('catalog_updated.xml');
echo 'Файл обновлён';
Файл обновлён

Пример 3: обработка XML с пространствами имён (namespace) через SimpleXML

Пример

$xmlString = '<ns:root xmlns:ns="http://example.com/ns"><ns:item id="1">Значение</ns:item></ns:root>';
$xml = simplexml_load_string($xmlString);
$ns = $xml->children('http://example.com/ns');
echo $ns->item['id']; // 1
echo $ns->item; // Значение

Пример 4: валидация XML по XSD-схеме с помощью DOMDocument

Пример

$dom = new DOMDocument();
$dom->load('data.xml');
if ($dom->schemaValidate('schema.xsd')) {
    echo 'XML корректен';
} else {
    echo 'Ошибка валидации';
}
XML корректен

Пример 5: потоковый парсинг с XMLReader и создание SimpleXML-объекта из фрагмента

Пример

$reader = new XMLReader();
$reader->open('large.xml');
while ($reader->read()) {
    if ($reader->nodeType == XMLREADER::ELEMENT && $reader->localName == 'record') {
        $record = simplexml_load_string($reader->readOuterXml());
        echo 'ID: ' . $record['id'] . ', Name: ' . $record->name . "\n";
    }
}
$reader->close();
ID: 1, Name: Первая запись
ID: 2, Name: Вторая запись
...

Работа с XML в PHP - comments

En
Xml файл php (php)