Skip to content

Instantly share code, notes, and snippets.

@flevour
Created March 28, 2012 10:13
Show Gist options
  • Save flevour/2225202 to your computer and use it in GitHub Desktop.
Save flevour/2225202 to your computer and use it in GitHub Desktop.
Xml SAX implementation example
<?php
$reader = new ExampleDataSource("posts.xml");
foreach ($reader as $post) {
// $post e' un array con chiavi 'title' e 'body'
}
<?xml>
<results>
<post>
<titleStrangeTag>Title</titleStrangeTag>
<content>Body of the post</content>
</post>
<post>
<titleStrangeTag>Title 2</titleStrangeTag>
<content>Body of the post 2</content>
</post>
</results>
<?php
/**
* Description of AbstractXmlDataSource
*
* @author flevour
*/
abstract class AbstractXmlDataSource implements \Iterator
{
protected $reader;
protected $tagName;
public function __construct($dataFile)
{
$this->tagName = $this->getTagName();
$this->reader = new \XMLReader;
$this->reader->open($dataFile);
// move to the first <TAGNAME /> node
while ($this->reader->read() && $this->reader->name !== $this->tagName)
;
}
/**
* Defines the tag to loop for in the XML file.
*
* @return string the tag name (case sensitive) containing a single information in the XML.
*/
abstract public function getTagName();
/**
* Defines a mapper from a SimpleXMLElement to an array containing the extracted information.
*
* @return array a keyed array containing the data extracted from the current node.
*/
abstract protected function mapData(\SimpleXMLElement $node);
/**
* Implementazione Iterator
*/
public function current()
{
$doc = new \DOMDocument;
$node = simplexml_import_dom($doc->importNode($this->reader->expand(), true));
$data = $this->mapData($node);
return $data;
}
public function next()
{
// go to next <TAG_NAME />
$this->reader->next($this->tagName);
}
/**
* Quando l'xml e' stato passato tutto, reader->name sara' nullo pertanto anche
* questo iteratore deve terminare.
* @return boolean
*/
public function valid()
{
return $this->reader->name === $this->tagName;
}
/**
* Non implementato, non ha senso parlare di una chiave in questo contesto.
* Il curorse nell'xml puo' solo avanzare.
*/
public function key()
{
}
/**
* Il curorse nell'xml puo' solo avanzare.
*/
public function rewind()
{
}
}
<?php
/**
* Description of ExampleDataSource
*
* @author flevour
*/
class ExampleDataSource extends AbstractXmlDataSource
{
public function getTagName()
{
return 'post';
}
protected function mapData(\SimpleXMLElement $node)
{
// now you can use $node without going insane about parsing
return array(
'title' => trim((string) $node->titleStrangeTag),
'body' => (string) $node->content,
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment