W3docs

xml_set_start_namespace_decl_handler()

Функция xml_set_start_namespace_decl_handler() устанавливает пользовательскую функцию-обработчик для начала объявлений пространств имён XML

Функция xml_set_start_namespace_decl_handler() регистрирует обратный вызов, который XML-парсер вызывает каждый раз при обнаружении начала объявления пространства имён — то есть атрибута xmlns или xmlns:prefix, вводящего пространство имён в область видимости. Она относится к низкоуровневому событийному расширению XML Parser (SAX) и не связана с SimpleXML или DOM, которые разбирают весь документ в дерево вместо потоковой обработки событий.

Этот обработчик используется при разборе больших или потоковых XML-документов, когда необходимо знать активные пространства имён — например, для сопоставления префиксов с URI, проверки наличия обязательного пространства имён или маршрутизации элементов к разным процессорам в зависимости от их пространства имён.

Ключевое требование: обработчики пространств имён срабатывают только если парсер поддерживает пространства имён. Необходимо создавать парсер с помощью xml_parser_create_ns(), а не xml_parser_create(). Обычный парсер молча игнорирует атрибуты xmlns, поэтому этот обработчик никогда не будет вызван.

Синтаксис

xml_set_start_namespace_decl_handler($parser, $handler): bool
ПараметрОписание
$parserПоддерживающий пространства имён XML-парсер, созданный функцией xml_parser_create_ns().
$handlerОбратный вызов, выполняемый при каждом событии начала пространства имён. Передайте имя функции (string), замыкание или null для удаления ранее установленного обработчика.

Функция возвращает true в случае успеха или false в случае ошибки.

Сигнатура обратного вызова

Обработчик получает три аргумента:

function handler($parser, $prefix, $uri): void
  • $parser — парсер, вызвавший событие.
  • $prefix — префикс пространства имён, например "ns" для xmlns:ns="…". Для пространства имён по умолчанию (xmlns="…") префикс является булевым false, а не пустой строкой.
  • $uri — URI пространства имён, к которому привязан префикс.

Пример: чтение объявлений пространств имён

Приведённый ниже пример разбирает документ в стиле Atom с двумя пространствами имён и выводит каждое из них по мере его вхождения в область видимости. Обратите внимание на использование xml_parser_create_ns(), чтобы события действительно срабатывали:

function handleStartNamespace($parser, $prefix, $uri) {
    // A default namespace (xmlns="...") arrives as prefix === false.
    $name = ($prefix === false) ? "(default)" : $prefix;
    echo "Namespace in scope -> $name = $uri\n";
}

$parser = xml_parser_create_ns();
xml_set_start_namespace_decl_handler($parser, "handleStartNamespace");

$xml = '<?xml version="1.0"?>
<root xmlns:ns="http://example.com/ns"
      xmlns:meta="http://example.com/meta">
  <ns:item>Test</ns:item>
</root>';

// The third argument `true` marks this as the final chunk of data.
xml_parse($parser, $xml, true);
xml_parser_free($parser);

Вывод:

Namespace in scope -> ns = http://example.com/ns
Namespace in scope -> meta = http://example.com/meta

Парсер вызывает одно событие для каждого объявленного пространства имён в порядке следования атрибутов xmlns, до того как сообщить об элементе, в котором они объявлены.

Распространённые ошибки

  • Обычный парсер не генерирует события. Если создать парсер с помощью xml_parser_create() вместо xml_parser_create_ns(), обработчик никогда не вызывается и вывода не будет — частый источник путаницы «почему не работает».
  • Префикс пространства имён по умолчанию равен false. Всегда используйте сравнение с === ($prefix === false); проверка if (!$prefix) также захватывает допустимый префикс "0".
  • Использовать в паре с обработчиком конца. Парный обработчик xml_set_end_namespace_decl_handler() отмечает, когда пространство имён выходит из области видимости, что важно при отслеживании вложенности.
  • Освобождать парсер. Вызывайте xml_parser_free() после завершения работы для освобождения ресурса.

Связанные функции

  • xml_parser_create_ns() — создаёт парсер с поддержкой пространств имён, необходимый для этого обработчика.
  • xml_set_end_namespace_decl_handler() — парный обработчик конца области видимости.
  • xml_set_element_handler() — обработка открывающих и закрывающих тегов элементов.
  • xml_parse() — передача данных парсеру и запуск обратных вызовов.

Заключение

xml_set_start_namespace_decl_handler() позволяет реагировать на пространства имён по мере их вхождения в область видимости при потоковой обработке XML с помощью SAX-парсера. Главная ошибка связана с парсером: события пространств имён срабатывают только когда парсер создан с помощью xml_parser_create_ns(). Помните, что пространство имён по умолчанию поступает с префиксом false, используйте обработчик в паре с xml_set_end_namespace_decl_handler() при необходимости отслеживания области видимости и освобождайте парсер после завершения работы.

Практика

Практика
Что делает функция xml_set_start_namespace_decl_handler() в PHP?
Что делает функция xml_set_start_namespace_decl_handler() в PHP?
Was this page helpful?