Xml set character data handler: примеры (PHP)

Парсинг XML данных через обработчик символьных данных
Раздел: XML
xml_set_character_data_handler(resource parser, callable handler): bool

XML обработчик символьных данных в PHP

Назначение функции xml_set_character_data_handler

Функция xml_set_character_data_handler() является частью расширения XML Parser в PHP. Она регистрирует пользовательский обработчик для символьных данных, которые находятся внутри элементов XML. Функция используется при последовательном парсинге XML-документов, когда важно обрабатывать текстовое содержимое по мере его чтения, не загружая весь документ в память.

Аргументы функции

Синтаксис функции: bool xml_set_character_data_handler(resource $parser, callable $handler)

  • $parser — обязательный параметр. Ссылка на XML-парсер, созданный функцией xml_parser_create().
  • $handler — обязательный параметр. Имя функции или анонимная функция, которая будет вызываться при нахождении символьных данных. Обработчик принимает два аргумента: ресурс парсера и строку с символьными данными.

Практическое применение функции

Базовый пример парсинга XML

Пример обработки текста внутри тегов:

$xml = <<<XML
<book>
  <title>PHP 8 Basics</title>
  <description>A guide to modern PHP</description>
</book>
XML;

$parser = xml_parser_create();
xml_set_element_handler($parser, "startElement", "endElement");
xml_set_character_data_handler($parser, "characterData");

function startElement($parser, $name, $attrs) {
    echo "Открыт тег: $name<br>";
}

function endElement($parser, $name) {
    echo "Закрыт тег: $name<br>";
}

function characterData($parser, $data) {
    if (trim($data) !== '') {
        echo "Найдены данные: '" . htmlspecialchars($data) . "'<br>";
    }
}

xml_parse($parser, $xml);
xml_parser_free($parser);
Открыт тег: BOOK
Открыт тег: TITLE
Найдены данные: 'PHP 8 Basics'
Закрыт тег: TITLE
Открыт тег: DESCRIPTION
Найдены данные: 'A guide to modern PHP'
Закрыт тег: DESCRIPTION
Закрыт тег: BOOK

Аналогичные средства в PHP

SimpleXML

Расширение SimpleXML преобразует XML-документ в объект, обеспечивая простой доступ к данным через свойства объектов. Подходит для небольших и структурно простых XML-файлов. Не требует написания обработчиков.

DOMDocument

Объектная модель документа реализует W3C DOM интерфейс. Позволяет не только читать, но и создавать, модифицировать XML-документы. Требует больше памяти, чем последовательный парсинг, но предоставляет более богатый API.

XMLReader

Обеспечивает последовательное чтение XML-документов с низким потреблением памяти, аналогично xml_set_character_data_handler, но через объектно-ориентированный интерфейс. Считается более современной альтернативой.

Решения в других языках программирования

Python: xml.sax
import xml.sax

class CharacterDataHandler(xml.sax.ContentHandler):
    def characters(self, content):
        if content.strip():
            print(f"Найдены данные: '{content}'")

parser = xml.sax.make_parser()
parser.setContentHandler(CharacterDataHandler())
parser.parse("data.xml")

Особенность: объектно-ориентированный подход, обязательное создание класса-обработчика.

JavaScript: SAX-парсеры для Node.js
const sax = require('sax');
const parser = sax.parser(true);

parser.ontext = function(text) {
    if (text.trim()) {
        console.log(`Найдены данные: '${text}'`);
    }
};

parser.write('<book>PHP 8 Basics</book>').close();

Особенность: событийно-ориентированная модель, асинхронная обработка.

Распространенные ошибки разработчиков

Неочищенные пробельные символы
function characterData($parser, $data) {
    echo "Данные: '$data'";
}
// Для XML "<a>\n   text\n</a>" функция может быть вызвана несколько раз для фрагментов.
Отсутствие обработки сущностей
// Если XML содержит &amp;, парсер передаст '&' в обработчик.
// Для корректного отображения может потребоваться htmlspecialchars().
Игнорирование кодировки
$parser = xml_parser_create();
// При несовпадении кодировки XML и парсера возникают искажения.
xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, 'UTF-8');

Эволюция функции в PHP

Функция xml_set_character_data_handler() появилась в PHP 4 и осталась практически неизменной в PHP 8. Основные изменения связаны с улучшением стабильности и совместимости расширения XML Parser. В PHP 8 улучшена обработка ошибок и приведение типов аргументов, но сигнатура функции и её поведение сохранены для обратной совместимости.

Сложные сценарии использования

Накопление текста из нескольких вызовов
Пример php
$currentText = '';

function characterData($parser, $data) {
    global $currentText;
    $currentText .= $data;
}

function endElement($parser, $name) {
    global $currentText;
    if ($name === 'TITLE' && trim($currentText) !== '') {
        echo "Полный текст тега: $currentText<br>";
    }
    $currentText = '';
}
Парсинг большого файла с фильтрацией
Пример php
$targetTag = false;
$searchText = '';

function startElement($parser, $name, $attrs) {
    global $targetTag;
    if ($name === 'PRICE') {
        $targetTag = true;
    }
}

function characterData($parser, $data) {
    global $targetTag, $searchText;
    if ($targetTag) {
        $searchText .= $data;
    }
}

function endElement($parser, $name) {
    global $targetTag, $searchText;
    if ($name === 'PRICE') {
        $price = (float) trim($searchText);
        if ($price > 100) {
            echo "Найдена цена: $price<br>";
        }
        $targetTag = false;
        $searchText = '';
    }
}
Обработка CDATA-секций

Символьные данные из секций CDATA также передаются в этот обработчик, что позволяет единообразно обрабатывать весь текст.

PHP xml_set_character_data_handler function comments

En
Xml set character data handler Set up character data handler