W3docs

xml_set_notation_decl_handler()

Функция xml_set_notation_decl_handler() регистрирует пользовательский обработчик объявлений нотаций в XML-парсере PHP.

Функция xml_set_notation_decl_handler() регистрирует пользовательский callback, который SAX-парсер (Expat) вызывает при каждом обнаружении объявления нотации в DTD документа. Она принадлежит расширению PHP xml и работает только с парсером, созданным через xml_parser_create() — на SimpleXML или DOM она не влияет.

Объявление нотации внутри <!DOCTYPE ...> выглядит следующим образом:

<!NOTATION png SYSTEM "image/png">

Нотации именуют внешний формат данных (тип изображения, вспомогательную программу и т. д.), чтобы впоследствии на этот формат можно было ссылаться через непарсируемую сущность. В современном XML нотации встречаются редко, но если DTD их содержит, данный обработчик позволяет перехватывать, журналировать или проверять каждую из них во время разбора вместо молчаливого игнорирования.

Примечание: Расширение xml (Expat) должно быть включено в вашей сборке PHP. Объявления нотаций появляются только внутри внутреннего или внешнего DTD, поэтому в документе без <!DOCTYPE> данный обработчик никогда не сработает.

Синтаксис

xml_set_notation_decl_handler(
    XMLParser $parser,
    callable|false $handler
): bool
  • $parser — ресурс парсера, возвращённый функцией xml_parser_create() (или xml_parser_create_ns()).
  • $handler — callback, вызываемый для каждого объявления нотации, или false для удаления ранее установленного обработчика.

Функция возвращает true в случае успеха и false, если $parser не является допустимым парсером.

Сигнатура callback

Обработчик получает пять аргументов в строго определённом порядке:

function handler($parser, $notation_name, $base, $system_id, $public_id)
ПараметрОписание
$parserПарсер, инициировавший вызов обработчика.
$notation_nameИмя нотации, например png.
$baseБазовый URI для разрешения идентификаторов (обычно пустой).
$system_idСистемный идентификатор (SYSTEM), или ""/null, если отсутствует.
$public_idПубличный идентификатор (PUBLIC), или ""/null, если отсутствует.

Нотация может использовать SYSTEM (только системный идентификатор) или PUBLIC (публичный идентификатор и системный), поэтому перед использованием проверяйте, какие поля заполнены.

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

Следующий парсер выводит каждую найденную нотацию, включая формы SYSTEM и PUBLIC:

function handle_notation_decl($parser, $notation_name, $base, $system_id, $public_id) {
    echo "Notation name: $notation_name\n";
    echo "  System ID:   " . ($system_id ?? '(none)') . "\n";
    echo "  Public ID:   " . ($public_id ?? '(none)') . "\n";
}

$xml_parser = xml_parser_create();
xml_set_notation_decl_handler($xml_parser, "handle_notation_decl");

$xml_data = <<<XML
<?xml version="1.0"?>
<!DOCTYPE root [
  <!NOTATION png SYSTEM "image/png">
  <!NOTATION gif PUBLIC "-//IETF//NOTATION GIF89a//EN" "http://www.w3.org/Graphics/GIF/spec-gif89a.txt">
]>
<root/>
XML;

if (!xml_parse($xml_parser, $xml_data, true)) {
    echo "XML error: " . xml_error_string(xml_get_error_code($xml_parser)) . "\n";
}
xml_parser_free($xml_parser);

Результат выполнения:

Notation name: png
  System ID:   image/png
  Public ID:   (none)
Notation name: gif
  System ID:   http://www.w3.org/Graphics/GIF/spec-gif89a.txt
  Public ID:   -//IETF//NOTATION GIF89a//EN

Обратите внимание: для нотации SYSTEM задан только системный идентификатор, тогда как для нотации PUBLIC заполнены оба идентификатора. Третий аргумент true в функции xml_parse() означает, что данные являются финальным фрагментом, а xml_parser_free() освобождает парсер по завершении работы.

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

  • Нет DTD — нет callback. Обработчик срабатывает только для объявлений <!NOTATION>, которые находятся внутри <!DOCTYPE>. В обычном документе без DOCTYPE он никогда не вызывается.
  • Регистрируйте до начала разбора. Устанавливайте обработчик до первого вызова xml_parse(); объявления сообщаются по мере чтения парсером DTD.
  • Используйте метод класса как callback. Передавайте [$object, 'method'] (или привяжите с помощью xml_set_object()), если обработчик является методом класса.
  • Сочетайте с непарсируемыми сущностями. Нотации обычно указываются в сущностях NDATA — обрабатывайте их с помощью xml_set_unparsed_entity_decl_handler().

Связанные обработчики

xml_set_notation_decl_handler() — один из нескольких SAX-callback, которые можно подключить к одному парсеру:

Заключение

xml_set_notation_decl_handler() позволяет перехватывать объявления <!NOTATION> в процессе SAX-разбора вместо их игнорирования. Зарегистрируйте callback с пятью аргументами до начала разбора, изучите получаемые системный и публичный идентификаторы и комбинируйте функцию с другими обработчиками xml_set_* для полноценной обработки документа с DTD. Для более широкого контекста смотрите главу PHP XML Parser.

Практика

Практика
Сколько аргументов получает callback функции xml_set_notation_decl_handler()?
Сколько аргументов получает callback функции xml_set_notation_decl_handler()?
Was this page helpful?