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údovo – SAX 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.