| 
<?phpif(version_compare(PHP_VERSION, '5.3.0', '<'))
 die('These classes are using Closures and other features that are available since PHP version 5.3.0. You are running PHP version '.PHP_VERSION.'. Please update your PHP.');
 
 class DomQuery implements Iterator
 {
 public static $prototype    = array();
 public $items                = array();
 protected $position            = 0;
 
 public function __construct($context)
 {
 if($context instanceof DomNode)
 $this->items[] = $context;
 elseif($context instanceof Iterator || $context instanceof DomNodeList || is_array($context))
 {
 foreach($context as $node)
 if($node instanceof DomNode)
 $this->items[] = $node;
 }
 else
 throw new Exception('Context must be instance of DomQuery, DomNode, DomNodeList or Array, but it is instance of '.get_class($context));
 }
 
 public function __call($method, $params)
 {
 $result = array();
 if(!isset(self::$prototype[$method]) || !(self::$prototype[$method] instanceof Closure))
 throw new Exception('Closure "'.$method.'" not found.');
 $closure = self::$prototype[$method];
 return $closure($this, $params);
 }
 
 public function get($index)
 {
 if(isset($this->items[$index]))
 return $this->items[$index];
 }
 
 public function each(Closure $method)
 {
 foreach($this->items as $index => $context)
 $method($context, $index);
 return $this;
 }
 
 public function rewind() {$this->position = 0;}
 public function valid() {return $this->position < count($this->items);}
 public function key() {return $this->position;}
 public function current() {return $this->items[$this->position];}
 public function next() {$this->position++;}
 
 public function __toString()
 {
 return '';
 }
 }
 
 DomQuery::$prototype = array
 ( 'find' => function(DomQuery $context, Array $params)
 {
 $result = array();
 foreach($context->items as $item)
 {
 $xpath = new DomXPath($item instanceof DomDocument ? $item : $item->ownerDocument);
 foreach($xpath->query($params[0], $item) as $resultNode)
 $result[] = $resultNode;
 }
 return new DomQuery($result);
 }
 , 'val' => function(DomQuery $context, Array $params)
 {
 if(isset($params[0]))
 {
 $context->each(
 function($node) use ($params)
 {
 while($firstChild = $node->firstChild)
 $node->removeChild($firstChild);
 $node->appendChild($node->ownerDocument->createTextNode($params[0]));
 }
 );
 return $context;
 }
 return $context->get(0)->nodeValue;
 }
 , 'attr' => function(DomQuery $context, Array $params)
 {
 if(isset($params[1]))
 {
 $context->each(
 function($node) use ($params)
 {
 $node->setAttribute($params[0], $params[1]);
 }
 );
 return $context;
 }
 return $context->get(0)->getAttribute($params[0]);
 }
 , 'removeAttr' => function(DomQuery $context, Array $params)
 {
 $context->each(function($node) use ($params) {$node->removeAttribute($params[0]);});
 return $context;
 }
 , 'xml' => function(DomQuery $context, Array $params)
 {
 if(!isset($params[0]))
 return $context->get(0);
 $xml = new DomDocument();
 if(strlen($params[0]) < 4)
 $new = $xml->createTextNode('');
 else
 {
 $xml->preserveWhiteSpace = false;
 $xml->formatOutput = true;
 $xml->loadXML($params[0]);
 $new = $xml->documentElement;
 }
 $newNodes = array();
 foreach($context->items as $node)
 {
 if($node->parentNode)
 {
 while($firstChild = $node->firstChild)
 $node->removeChild($firstChild);
 $node->appendChild($newNodes[] = $node->ownerDocument->importNode($new));
 }
 }
 return $context;
 }
 );
 
 function DQ($context)
 {
 return new DomQuery($context);
 }
 function DomQuery($context)
 {
 return new DomQuery($context);
 }
 
 |