-
-
Save M8R-1jmw5r/775cd8cc47e22209873d to your computer and use it in GitHub Desktop.
DOMValueObject and DOMValueCollection
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
* DOMValueObject and DOMValueCollection | |
* | |
* @author Frank Hilvestede | |
*/ | |
/** | |
* Class DOMValueCollection | |
* | |
* @author Frank Hilvestede | |
*/ | |
class DOMValueObject | |
{ | |
/** | |
* @var DOMNode | |
*/ | |
private $contextNode; | |
/** | |
* @var array | |
*/ | |
private $definitions; | |
public function __construct(DOMNode $contextNode = null) { | |
$this->contextNode = $contextNode; | |
} | |
public function defineProperty($name, $expression, $default = NULL) { | |
$this->definitions[$name] = array($expression, $default); | |
} | |
/** | |
* @param $name | |
* | |
* @throws BadMethodCallException | |
* @return DOMNode|mixed|null | |
*/ | |
function __get($name) { | |
if (!isset($this->definitions[$name])) { | |
throw new BadMethodCallException(sprintf("Not a property: %s", $name)); | |
} | |
list($expression, $default) = $this->definitions[$name]; | |
$xpath = new DOMXPath($this->contextNode->ownerDocument); | |
$result = $xpath->evaluate($expression, $this->contextNode); | |
if (FALSE === $result) { | |
return $default; | |
} | |
if ($result instanceof DOMNodeList) { | |
$result = $result->length ? $result->item(0) : $default; | |
} | |
return $result; | |
} | |
public function setContextNode(DOMNode $contextNode) { | |
$this->contextNode = $contextNode; | |
} | |
public function getPropertyExpression($name) { | |
return $this->definitions[$name][0]; | |
} | |
/** | |
* @return array | |
*/ | |
public function getObjectProperties() { | |
$props = array(); | |
foreach ($this->definitions as $name => $def) { | |
$value = $this->__get($name); | |
$props[$name] = $this->valuefy($value); | |
} | |
return $props; | |
} | |
private function valuefy($mixed) { | |
if ($mixed instanceof DOMNode) { | |
return $mixed->nodeValue; | |
} | |
return $mixed; | |
} | |
} | |
/** | |
* Class DOMValueCollection | |
* | |
* @author Frank Hilvestede | |
*/ | |
class DOMValueCollection implements Iterator, countable | |
{ | |
private $doc; | |
private $xpath; | |
/** | |
* @var Iterator|DOMNodeList | |
*/ | |
private $result; | |
public function __construct(DOMDocument $doc, $xpath) { | |
$this->doc = $doc; | |
$this->xpath = $xpath; | |
} | |
public function getArrayCopy() { | |
$copy = array(); | |
/* @var $this DOMValueObject[] */ | |
foreach ($this as $object) { | |
$copy[] = $object->getObjectProperties(); | |
} | |
return $copy; | |
} | |
public function count() { | |
return $this->result ? $this->result->length : 0; | |
} | |
public function rewind() { | |
$xpath = new DOMXPath($this->doc); | |
$result = $xpath->query($this->xpath); | |
if (FALSE === $result) { | |
throw new LogicException(sprintf('Xpath expression failed: %s', $this->xpath)); | |
} | |
$this->result = new IteratorIterator($result); | |
$this->result->rewind(); | |
} | |
public function current() { | |
$node = $this->result->current(); | |
return new DOMValueObject($node); | |
} | |
public function next() { | |
$this->result->next(); | |
} | |
public function key() { | |
return $this->result->key(); | |
} | |
public function valid() { | |
return $this->result->valid(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment