To get more flexibility with XMLReader , I usually create iterators for myself that can work with the XMLReader object and provide the steps I need .
This starts with a simple iteration over all nodes to iteration over the elements, optionally with a specific name. Let us call the last XMLElementIterator , taking the reader and element name as parameters.
In your scenario, I would then create an iterator that returns a SimpleXMLElement for the current element, taking only the <headend> elements:
require('xmlreader-iterators.php'); // https://gist.github.com/hakre/5147685 class HeadendIterator extends XMLElementIterator { const ELEMENT_NAME = 'headend'; public function __construct(XMLReader $reader) { parent::__construct($reader, self::ELEMENT_NAME); } /** * @return SimpleXMLElement */ public function current() { return simplexml_load_string($this->reader->readOuterXml()); } }
Equipped with this iterator, the rest of your work is basically a piece of cake. First upload a 10 gigabyte file:
$pc = "78746"; $xmlfile = '../data/lineups.xml'; $reader = new XMLReader(); $reader->open($xmlfile);
And then check if the <headend> element contains this information, and if so, display the / XML data:
foreach (new HeadendIterator($reader) as $headend) { if (!$headend->xpath("/*/postalCodes/postalCode[. = '$pc']")) { continue; } echo 'Found, name: ', $headend->name, "\n"; echo "==========================================\n"; $headend->asXML('php://stdout'); }
This literally does what you are trying to achieve: go through a large document (which is memory friendly) until you find the elements you are interested in. Then you process the specific element and its XML only; XMLReader::readOuterXml() is a great tool here.
Sample output:
Found, name: Grande Gables at The Terrace ========================================== <?xml version="1.0"?> <headend headendId="TX02217"> <name>Grande Gables at The Terrace</name> <mso msoId="17541">Grande Communications</mso> <marketIds> <marketId type="DMA">635</marketId> </marketIds> <postalCodes> <postalCode>11111</postalCode> <postalCode>22222</postalCode> <postalCode>33333</postalCode> <postalCode>78746</postalCode> </postalCodes> <location>Austin</location> <lineup> <station prgSvcId="20014"> <chan effDate="2006-01-16" tier="1">002</chan> </station> <station prgSvcId="10722"> <chan effDate="2006-01-16" tier="1">003</chan> </station> </lineup> <areasServed> <area> <community>Thorndale</community> <county code="45331" size="D">Milam</county> <state>TX</state> </area> <area> <community>Thrall</community> <county code="45491" size="B">Williamson</county> <state>TX</state> </area> </areasServed> </headend>