xml_set_element_handler()
A função xml_set_element_handler() define funções de usuário como manipuladores para as tags de abertura e fechamento de um elemento XML.
xml_set_element_handler() registra dois callbacks em um parser XML: um que é acionado cada vez que o parser encontra uma tag de abertura (<book>) e outro que é acionado a cada tag de fechamento (</book>). Ela pertence ao parser Expat baseado em eventos do PHP — a família xml_parser_* — e não ao SimpleXML ou DOM. Enquanto o SimpleXML carrega o documento inteiro em uma árvore na memória, o Expat percorre o documento em streaming e chama seus manipuladores conforme avança, o que o torna bem adequado para arquivos grandes que você não deseja carregar de uma só vez.
Esta página aborda a assinatura da função, os argumentos exatos que seus manipuladores recebem, um exemplo completo e executável, e as armadilhas comuns (conversão de maiúsculas nos nomes de tags e a forma de callback com método de objeto).
Sintaxe
xml_set_element_handler(
XMLParser $parser,
callable $start_handler,
callable $end_handler
): bool| Parâmetro | Descrição |
|---|---|
$parser | O parser criado por xml_parser_create(). |
$start_handler | Chamado em cada tag de abertura. Recebe ($parser, $name, $attributes). |
$end_handler | Chamado em cada tag de fechamento. Recebe ($parser, $name). |
A função retorna true em caso de sucesso e false em caso de falha. Um callback pode ser fornecido como uma string com o nome da função ("startTag"), uma closure, ou um par objeto-método ([$object, 'method']).
O que os manipuladores recebem
- Manipulador de início —
$nameé o nome da tag e$attributesé um array associativo com os atributos daquela tag (['ID' => 'b1']). - Manipulador de fim — apenas
$name, pois as tags de fechamento não carregam atributos.
Por padrão, o Expat converte os nomes de tags e atributos para maiúsculas (
<book>chega comoBOOK). Compare nomes sem distinção de maiúsculas e minúsculas, ou desative a conversão comxml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false). Vejaxml_parser_set_option().
Exemplos de Uso
Exemplo: Imprimindo a árvore de elementos
Este script completo analisa uma string XML e usa os manipuladores de início/fim para imprimir um esboço recuado do documento, incluindo os atributos de cada tag.
<?php
$xml = '<?xml version="1.0"?>
<library>
<book id="b1">PHP Basics</book>
<book id="b2">Advanced XML</book>
</library>';
$depth = 0;
function startTag($parser, $name, $attrs) {
global $depth;
echo str_repeat(" ", $depth) . "START: $name";
foreach ($attrs as $key => $value) {
echo " ($key=\"$value\")";
}
echo "\n";
$depth++;
}
function endTag($parser, $name) {
global $depth;
$depth--;
echo str_repeat(" ", $depth) . "END: $name\n";
}
$parser = xml_parser_create();
xml_set_element_handler($parser, "startTag", "endTag");
if (!xml_parse($parser, $xml, true)) {
die(sprintf(
"XML error: %s at line %d",
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)
));
}
xml_parser_free($parser);Saída:
START: LIBRARY
START: BOOK (ID="b1")
END: BOOK
START: BOOK (ID="b2")
END: BOOK
END: LIBRARYObserve que library chega como LIBRARY e id como ID: essa é a conversão de maiúsculas mencionada acima. O terceiro argumento de xml_parse() é definido como true para informar ao parser que este é o trecho final (e único) de dados. Sempre libere o parser com xml_parser_free() ao terminar.
Exemplo: Usando um método de objeto como manipulador
Os manipuladores não precisam ser funções livres. Passar [$object, 'method'] permite que você mantenha o estado de análise em um objeto em vez de em variáveis globais — útil quando vários manipuladores precisam compartilhar dados.
<?php
$xml = '<note><to>Tove</to><from>Jani</from></note>';
class TagCounter {
public int $open = 0;
public function onStart($parser, $name, $attrs) { $this->open++; }
public function onEnd($parser, $name) {}
}
$counter = new TagCounter();
$parser = xml_parser_create();
xml_set_element_handler($parser, [$counter, 'onStart'], [$counter, 'onEnd']);
xml_parse($parser, $xml, true);
xml_parser_free($parser);
echo "Opening tags seen: {$counter->open}\n";Saída:
Opening tags seen: 3Quando usar
Recorra aos manipuladores Expat quando precisar de uma passagem em streaming e com pouco uso de memória sobre XML — feeds grandes, arquivos de log ou sitemaps — ou quando você se preocupa apenas com algumas tags e não quer construir uma árvore completa. Para ler o texto dentro de um elemento (o PHP Basics em <book>PHP Basics</book>), combine isso com xml_set_character_data_handler(). Se preferir consultar um documento pequeno com acesso semelhante ao XPath, o SimpleXML é mais simples. Para uma visão geral de cada abordagem, consulte PHP XML Parsers.
Conclusão
xml_set_element_handler() conecta callbacks de tag de início e fim ao parser Expat orientado a eventos do PHP, permitindo que você reaja à estrutura de um documento conforme ele passa em streaming. Lembre-se dos três pontos essenciais: crie o parser primeiro, leve em conta os nomes de tags em maiúsculas e libere o parser ao terminar.