Xml set object: примеры (PHP)

Использование xml_set_object для парсинга XML в PHP
Раздел: XML
xml_set_object(resource parser, object object): bool

Функция xml_set_object в PHP

Функция xml_set_object предназначена для связывания XML-парсера с объектом, что позволяет использовать методы этого объекта в качестве обработчиков событий парсера. Её применение актуально при объектно-ориентированном подходе к разбору XML-документов.

Аргументы функции
  • parser (resource) – обязательный аргумент, ссылка на XML-парсер, созданный функцией xml_parser_create().
  • object (object) – обязательный аргумент, объект, методы которого будут вызываться в качестве обработчиков.

Примеры использования

Базовый пример

Связывание парсера с объектом и использование его методов.

<?php
class XMLParser {
    public function startElement($parser, $name, $attrs) {
        echo "Открыт элемент: $name
";
    }
    public function endElement($parser, $name) {
        echo "Закрыт элемент: $name
";
    }
}

$parser = xml_parser_create();
$obj = new XMLParser();
xml_set_object($parser, $obj);
xml_set_element_handler($parser, "startElement", "endElement");
xml_parse($parser, "<root><tag>text</tag></root>");
?>
Открыт элемент: ROOT
Открыт элемент: TAG
Закрыт элемент: TAG
Закрыт элемент: ROOT

Альтернативы в PHP

Для работы с XML в PHP доступны и другие подходы.

DOMDocument

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

SimpleXML

Упрощенный интерфейс для чтения и изменения XML-данных, предоставляющий доступ к элементам как к свойствам объекта. Идеален для простых XML-структур.

XMLReader

Потоковый парсер для последовательного чтения больших XML-файлов с минимальным потреблением памяти.

Альтернативы в других языках

Python (xml.etree.ElementTree)
import xml.etree.ElementTree as ET
xml_data = '<root><tag>text</tag></root>'
root = ET.fromstring(xml_data)
for elem in root.iter():
    print(elem.tag)
root
tag
JavaScript (DOMParser)
const parser = new DOMParser();
const xmlDoc = parser.parseFromString('<root><tag>text</tag></root>', 'text/xml');
console.log(xmlDoc.documentElement.nodeName);
root

Xml set object в MySQL

В MySQL функции для работы с XML, такие как ExtractValue(), используются для извлечения данных из XML-строк в запросах SQL.

Типичные ошибки

Передача несуществующего метода

Указание имени метода, который не существует в объекте, приводит к ошибке.

<?php
class Parser {}
$parser = xml_parser_create();
$obj = new Parser();
xml_set_object($parser, $obj);
xml_set_element_handler($parser, "nonExistentMethod", "endElement");
xml_parse($parser, "<root/>");
?>
Warning: xml_set_element_handler(): Unable to find handler nonExistentMethod in ...
Использование не объекта

Передача в функцию аргумента, который не является объектом, вызывает ошибку.

<?php
$parser = xml_parser_create();
xml_set_object($parser, 'not_an_object');
?>
Warning: xml_set_object() expects parameter 2 to be object, string given in ...

Изменения в PHP

В PHP 8 функция xml_set_object не претерпела значительных изменений. Однако важно отметить, что модуль XML Parser, частью которого является эта функция, остается стабильным. Все изменения в PHP 8 в основном связаны с улучшениями общей производительности и согласованности типов.

Расширенные примеры

Парсинг с сохранением данных в объект

Сбор данных из XML в свойства объекта во время разбора.

Пример php
<?php
class ProductParser {
    private $currentProduct = [];
    private $products = [];
    private $currentTag;

    public function startElement($parser, $name, $attrs) {
        $this->currentTag = $name;
        if ($name == 'PRODUCT') {
            $this->currentProduct = [];
        }
    }

    public function characterData($parser, $data) {
        if (in_array($this->currentTag, ['NAME', 'PRICE'])) {
            $this->currentProduct[strtolower($this->currentTag)] = trim($data);
        }
    }

    public function endElement($parser, $name) {
        if ($name == 'PRODUCT') {
            $this->products[] = $this->currentProduct;
        }
        $this->currentTag = '';
    }

    public function getProducts() {
        return $this->products;
    }
}

$xml = "
<catalog>
    <product>
        <name>Widget</name>
        <price>19.99</price>
    </product>
</catalog>
";
$parser = xml_parser_create();
$productParser = new ProductParser();
xml_set_object($parser, $productParser);
xml_set_element_handler($parser, "startElement", "endElement");
xml_set_character_data_handler($parser, "characterData");
xml_parse($parser, $xml);
print_r($productParser->getProducts());
?>
Array
(
    [0] => Array
        (
            [name] => Widget
            [price] => 19.99
        )

)
Обработка пространств имен

Использование функции совместно с обработчиками пространств имен XML.

Пример php
<?php
class NSHandler {
    public function startElementNS($parser, $prefix, $name, $uri) {
        echo "Элемент с NS: {$prefix}:{$name}
";
    }
}
$parser = xml_parser_create_ns();
$handler = new NSHandler();
xml_set_object($parser, $handler);
xml_set_start_namespace_decl_handler($parser, 'startElementNS');
xml_parse($parser, '<root xmlns:ns="http://example.com"><ns:child/></root>');
?>
Элемент с NS: ns:CHILD

PHP xml_set_object function comments

En
Xml set object Use XML Parser within an object