Parsovanie veľkých XML súborov v PHP

, Štítky: PHP, XML

Na spracovanie XML súborov v PHP sa bežne používajú knižnice DOM a SimpleXML. Obe fungujú ako tzv. DOM Parser – načítajú XML a v pamäti si vytvoria objektový graf.

Čo ak potrebujete spracovať súbor, ktorý má napr. 2 GB?

Pre takéto prípady potrebujete spracovávať dokument po častiach. V PHP máte 2 možnosti ako spracovávať XML prúdovoSAX a Pull Parsing.

SAX parser

SAX je skratka pre „Simple API for XML“. V PHP slúži k týmto účelom XML parser. Parser načítava súbor postupne, lexikálne ho analyzuje a vyvoláva udalosti. Jednotlivým udalostiam musíme zaregistrovať handlery, ktoré sa starajú o samotné spracovanie súboru.

$parser = xml_parser_create();

xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false);
 
xml_set_element_handler($parser, "start_element_handler", "end_element_handler");
 
xml_set_character_data_handler($parser, "handler");

/**
 * @param  resource $parser 
 * @param  string   $name   
 * @param  array    $attrs
 */
function start_element_handler($parser, $name, $attrs)
{}

/**
 * @param  resource $parser 
 * @param  string   $name
 */
function end_element_handler($parser, $name)
{}

/**
 * @param  resource $parser
 * @param  string   $data  
 */
function handler($parser, $data)
{}
 
if ($fp = fopen( __DIR__. "/feed.xml", "r" )) {

    while ($xml_data = fread($fp, 4096)) {

        xml_parse($parser, $xml_data, feof($fp));

    }
  
    fclose($fp);
}

xml_parser_free($parser);

Práca s týmto parserom je síce rýchla a jednoducho sa implementuje, ale pokiaľ potrebujete spracovať trochu zložitejšie dáta, bude to bolieť.

Pull parser

Tento parser načítava súbor trochu sofistikovanejšie. Prechádza súborom ako sériou jednotlivých uzlov, atribútov a hodnôt, čo umožňuje pohodlnejšiu prácu. V PHP nám tento spôsob umožňuje XML Reader. Skvele sa dá zkombinovať s vyššie zmienenými knižnicami DOM a SimpleXML.

$reader = new \XMLReader;

if (false == $reader->open(__DIR__ . '/feed.xml')) {
    throw new \Exception("Error: Cannot open XML file", 1);
}

// traverse to first <row /> element 
while ($reader->read() && 'row' !== $reader->name);

while ('row' === $reader->name) {

    $node = new \SimpleXMLElement($reader->readOuterXML());
            
    // do something with $node
    $xmlProcessor->processNode($node);

    $reader->next('row');
}

$reader->close();    

Práca s Pull parserom je tiež rýchla, nenáročná na systémové prostriedky a ľahká na implementáciu. Výhodou oproti SAX parseru je, že nám umožňuje spracovávať dáta zhora dolu rekurzívnym zostupom. Výsledný kód je prehľadnejší a ľahšie sa udržuje.

← Späť na zoznam