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() при необходимости отслеживания области видимости и освобождайте парсер после завершения работы.