W3docs

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âmetroDescrição
$parserO parser criado por xml_parser_create().
$start_handlerChamado em cada tag de abertura. Recebe ($parser, $name, $attributes).
$end_handlerChamado 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 como BOOK). Compare nomes sem distinção de maiúsculas e minúsculas, ou desative a conversão com xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false). Veja xml_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:   LIBRARY

Observe 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: 3

Quando 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.

Prática

Prática
Qual é o uso da função xml_set_element_handler() em PHP?
Qual é o uso da função xml_set_element_handler() em PHP?
Was this page helpful?