Skip to content

Instantly share code, notes, and snippets.

@hakre
Created September 27, 2013 19:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hakre/6733849 to your computer and use it in GitHub Desktop.
Save hakre/6733849 to your computer and use it in GitHub Desktop.
<?php
/**
* XObjects - XPath based Objects for SimpleXMLElement
*
* @author hakre <http://hakre.wordpress.com/credits/>
*/
/**
* Class XListIterator
*/
class XListIterator extends ArrayIterator
{
private $prototype;
public function __construct(SimpleXMLElement $doc, XPrototype $prototype)
{
parent::__construct($prototype->createNodeList($doc));
$this->prototype = $prototype;
}
public function current()
{
return $this->prototype->cast(parent::current());
}
}
/**
* Class XList
*/
class XList implements IteratorAggregate
{
private $doc;
private $proptype;
public static function createSimpleXMLelment($mixed)
{
if ($mixed instanceof SimpleXMLElement) {
return $mixed;
}
if (!(is_string($mixed) && strlen($mixed))) {
return NULL;
}
if ($mixed[0] === '<') {
return simplexml_load_string($mixed);
}
return simplexml_load_file($mixed);
}
public function __construct($doc, XPrototype $prototype)
{
$this->doc = self::createSimpleXMLelment($doc);
$this->proptype = $prototype;
}
public function getIterator()
{
return new XListIterator(
$this->doc,
$this->proptype
);
}
}
/**
* Class XPrototype
*/
class XPrototype
{
private $anchor;
/**
* @var array|string[]
*/
private $props;
/**
* @var array|string[]
*/
private $prefixes;
function __construct($anchor, array $props, array $prefixes = array())
{
$this->anchor = $anchor;
$this->props = $props;
$this->prefixes = $prefixes;
}
private function registerPrefixes(SimpleXMLElement $node)
{
$prefixes = $this->prefixes;
$prefixes += $node->getNamespaces(TRUE);
foreach ($prefixes as $prefix => $ns) {
$node->registerXPathNamespace($prefix, $ns);
}
}
public function createNodeList(SimpleXMLElement $from)
{
$this->registerPrefixes($from);
return $from->xpath($this->anchor);
}
public function cast(SimpleXMLElement $node)
{
$object = new stdClass();
foreach ($this->props as $name => $xprop) {
$this->registerPrefixes($node);
$value = $node->xpath($xprop);
$object->$name = $value ? (string)$value[0] : NULL;
}
return $object;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment