xml_set_notation_decl_handler()
The xml_set_notation_decl_handler() function is a PHP built-in function that sets a user-defined function as the handler for notation declarations in an XML
The xml_set_notation_decl_handler() function registers a user-defined callback that the SAX (Expat) parser invokes whenever it encounters a notation declaration in the document's DTD. It belongs to PHP's xml extension and works only with a parser created by xml_parser_create() — it has no effect on SimpleXML or DOM.
A notation declaration looks like this inside a <!DOCTYPE ...>:
<!NOTATION png SYSTEM "image/png">Notations name an external data format (an image type, a helper program, etc.) so that the format can later be referenced by an unparsed entity. They are rare in modern XML, but when a DTD contains them this handler lets you intercept, log, or validate each one during parsing instead of discarding it silently.
Note: The
xml(Expat) extension must be enabled in your PHP build. Notation declarations only appear inside an internal or external DTD, so a document with no<!DOCTYPE>never triggers this handler.
Syntax
xml_set_notation_decl_handler(
XMLParser $parser,
callable|false $handler
): bool$parser— the parser resource returned byxml_parser_create()(orxml_parser_create_ns()).$handler— the callback to run for each notation declaration, orfalseto remove a previously set handler.
It returns true on success and false if $parser is not a valid parser.
The callback signature
Your handler receives five arguments in this fixed order:
function handler($parser, $notation_name, $base, $system_id, $public_id)| Parameter | Meaning |
|---|---|
$parser | The parser that triggered the handler. |
$notation_name | The name given to the notation, e.g. png. |
$base | The base URI for resolving the identifiers (usually empty). |
$system_id | The SYSTEM identifier, or ""/null if absent. |
$public_id | The PUBLIC identifier, or ""/null if absent. |
A notation may use SYSTEM (system identifier only) or PUBLIC (public identifier and a system identifier), so check which fields are populated before relying on them.
Example: reading notation declarations
The following parser prints every notation it finds, including both SYSTEM and PUBLIC forms:
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);This prints:
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//ENNotice that for the SYSTEM notation only the system ID is set, while the PUBLIC notation fills in both identifiers. The third true argument to xml_parse() marks the data as the final chunk, and xml_parser_free() releases the parser when you are done.
Common gotchas
- No DTD, no callback. The handler fires only for
<!NOTATION>declarations, which live inside<!DOCTYPE>. A plain document never triggers it. - Register before parsing. Set the handler before the first call to
xml_parse(); declarations are reported as the parser reads the DTD. - Use a method as the callback. Pass
[$object, 'method'](or bind withxml_set_object()) when the handler lives on a class. - Pair with unparsed entities. Notations are normally referenced by
NDATAentities — handle those withxml_set_unparsed_entity_decl_handler().
Related handlers
xml_set_notation_decl_handler() is one of several SAX callbacks you can attach to the same parser:
xml_set_element_handler()— start and end tags.xml_set_character_data_handler()— text content.xml_set_unparsed_entity_decl_handler()— unparsed (NDATA) entities.xml_set_default_handler()— anything without a specific handler.
Conclusion
xml_set_notation_decl_handler() lets you intercept <!NOTATION> declarations during SAX parsing instead of ignoring them. Register a five-argument callback before parsing, inspect the system and public identifiers it receives, and combine it with the other xml_set_* handlers to process a DTD-driven document end to end. For broader context, see the PHP XML Parser chapter.