W3docs

xml_set_element_handler()

La funzione xml_set_element_handler() imposta funzioni definite dall'utente come handler per i tag di apertura e chiusura di un elemento XML in PHP.

xml_set_element_handler() registra due callback su un parser XML: una che si attiva ogni volta che il parser incontra un tag di apertura (<book>) e una che si attiva su ogni tag di chiusura (</book>). Appartiene al parser Expat basato sugli eventi di PHP — la famiglia xml_parser_* — non a SimpleXML o DOM. Mentre SimpleXML carica l'intero documento in un albero in memoria, Expat scorre il documento in streaming e chiama i tuoi handler man mano che procede, il che lo rende adatto a file di grandi dimensioni che non si vuole caricare tutti in una volta.

Questa pagina tratta la firma della funzione, gli argomenti esatti che ricevono i tuoi handler, un esempio completo eseguibile e le insidie più comuni (case folding dei nomi dei tag e la forma di callback con metodo di oggetto).

Sintassi

xml_set_element_handler(
    XMLParser $parser,
    callable  $start_handler,
    callable  $end_handler
): bool
ParametroDescrizione
$parserIl parser creato da xml_parser_create().
$start_handlerChiamato su ogni tag di apertura. Riceve ($parser, $name, $attributes).
$end_handlerChiamato su ogni tag di chiusura. Riceve ($parser, $name).

La funzione restituisce true in caso di successo e false in caso di errore. Una callback può essere fornita come stringa con il nome della funzione ("startTag"), come closure o come coppia oggetto-metodo ([$object, 'method']).

Cosa ricevono gli handler

  • Start handler$name è il nome del tag e $attributes è un array associativo degli attributi di quel tag (['ID' => 'b1']).
  • End handler — solo $name, poiché i tag di chiusura non portano attributi.

Per impostazione predefinita, Expat converte i nomi di tag e attributi in maiuscolo (<book> arriva come BOOK). Confronta i nomi senza distinzione tra maiuscole e minuscole, oppure disattiva il folding con xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false). Vedi xml_parser_set_option().

Esempi d'uso

Esempio: Stampa dell'albero degli elementi

Questo script completo analizza una stringa XML e usa gli handler di apertura/chiusura per stampare uno schema indentato del documento, inclusi gli attributi di ogni 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);

Output:

START: LIBRARY
  START: BOOK (ID="b1")
  END:   BOOK
  START: BOOK (ID="b2")
  END:   BOOK
END:   LIBRARY

Si noti che library arriva come LIBRARY e id come ID: è il case folding menzionato sopra. Il terzo argomento di xml_parse() è impostato su true per indicare al parser che questo è il blocco finale (e unico) di dati. Rilascia sempre il parser con xml_parser_free() al termine.

Esempio: Utilizzo di un metodo di oggetto come handler

Gli handler non devono essere funzioni libere. Passare [$object, 'method'] consente di mantenere lo stato del parsing su un oggetto invece che nelle variabili globali — utile quando più handler devono condividere dati.

<?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";

Output:

Opening tags seen: 3

Quando usarlo

Ricorri agli handler Expat quando hai bisogno di una lettura in streaming con basso consumo di memoria su XML — feed di grandi dimensioni, file di log o sitemap — oppure quando ti interessano solo alcuni tag e non vuoi costruire un albero completo. Per leggere il testo all'interno di un elemento (PHP Basics in <book>PHP Basics</book>), abbinalo a xml_set_character_data_handler(). Se preferisci interrogare un documento piccolo con accesso simile a XPath, SimpleXML è più semplice. Per una panoramica di ogni approccio, consulta PHP XML Parsers.

Conclusione

xml_set_element_handler() collega le callback di apertura e chiusura dei tag al parser Expat event-driven di PHP, permettendoti di reagire alla struttura di un documento mentre viene letto in streaming. Ricorda i tre elementi essenziali: crea prima il parser, tieni conto dei nomi dei tag in maiuscolo e libera il parser al termine.

Esercizio

Pratica
Qual è l'uso della funzione xml_set_element_handler() in PHP?
Qual è l'uso della funzione xml_set_element_handler() in PHP?
Was this page helpful?