How to use XMLReader in PHP? How to use XMLReader in PHP? xml xml

How to use XMLReader in PHP?


It all depends on how big the unit of work, but I guess you're trying to treat each <product/> nodes in succession.

For that, the simplest way would be to use XMLReader to get to each node, then use SimpleXML to access them. This way, you keep the memory usage low because you're treating one node at a time and you still leverage SimpleXML's ease of use. For instance:

$z = new XMLReader;$z->open('data.xml');$doc = new DOMDocument;// move to the first <product /> nodewhile ($z->read() && $z->name !== 'product');// now that we're at the right depth, hop to the next <product/> until the end of the treewhile ($z->name === 'product'){    // either one should work    //$node = new SimpleXMLElement($z->readOuterXML());    $node = simplexml_import_dom($doc->importNode($z->expand(), true));    // now you can use $node without going insane about parsing    var_dump($node->element_1);    // go to next <product />    $z->next('product');}

Quick overview of pros and cons of different approaches:

XMLReader only

  • Pros: fast, uses little memory

  • Cons: excessively hard to write and debug, requires lots of userland code to do anything useful. Userland code is slow and prone to error. Plus, it leaves you with more lines of code to maintain

XMLReader + SimpleXML

  • Pros: doesn't use much memory (only the memory needed to process one node) and SimpleXML is, as the name implies, really easy to use.

  • Cons: creating a SimpleXMLElement object for each node is not very fast. You really have to benchmark it to understand whether it's a problem for you. Even a modest machine would be able to process a thousand nodes per second, though.

XMLReader + DOM

  • Pros: uses about as much memory as SimpleXML, and XMLReader::expand() is faster than creating a new SimpleXMLElement. I wish it was possible to use simplexml_import_dom() but it doesn't seem to work in that case

  • Cons: DOM is annoying to work with. It's halfway between XMLReader and SimpleXML. Not as complicated and awkward as XMLReader, but light years away from working with SimpleXML.

My advice: write a prototype with SimpleXML, see if it works for you. If performance is paramount, try DOM. Stay as far away from XMLReader as possible. Remember that the more code you write, the higher the possibility of you introducing bugs or introducing performance regressions.


For xml formatted with attributes...

data.xml:

<building_data><building address="some address" lat="28.902914" lng="-71.007235" /><building address="some address" lat="48.892342" lng="-75.0423423" /><building address="some address" lat="58.929753" lng="-79.1236987" /></building_data>

php code:

$reader = new XMLReader();if (!$reader->open("data.xml")) {    die("Failed to open 'data.xml'");}while($reader->read()) {  if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'building') {    $address = $reader->getAttribute('address');    $latitude = $reader->getAttribute('lat');    $longitude = $reader->getAttribute('lng');}$reader->close();


The accepted answer gave me a good start, but brought in more classes and more processing than I would have liked; so this is my interpretation:

$xml_reader = new XMLReader;$xml_reader->open($feed_url);// move the pointer to the first productwhile ($xml_reader->read() && $xml_reader->name != 'product');// loop through the productswhile ($xml_reader->name == 'product'){    // load the current xml element into simplexml and we’re off and running!    $xml = simplexml_load_string($xml_reader->readOuterXML());    // now you can use your simpleXML object ($xml).    echo $xml->element_1;    // move the pointer to the next product    $xml_reader->next('product');}// don’t forget to close the file$xml_reader->close();