Created
July 14, 2015 21:42
-
-
Save hakre/c36a66708259f54e564a to your computer and use it in GitHub Desktop.
Recursive Method Calls with SimpleXML and DOMDocument Context
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 | |
/** | |
* Class ArrayXmlElement | |
* | |
* Use an array definition stored as XML to convert a tree structure from another DOMDocument | |
* | |
* @author hakre <http://hakre.wordpress.com> | |
*/ | |
class XmlArrayElement extends SimpleXMLElement | |
{ | |
/** | |
* setter for named fields on SimpleXMLElements | |
* | |
* @link https://hakre.wordpress.com/2015/03/27/the-simplexmlelement-magic-wonder-world-in-php/ | |
* | |
* @param string $name of the field | |
* @param mixed $value to store | |
*/ | |
public function setData($name, $value) | |
{ | |
$element = dom_import_simplexml($this); | |
$element->data[$name] = $value; | |
$element->circref = $element; | |
} | |
/** | |
* getter for named fields on SimpleXMLElements | |
* | |
* @link https://hakre.wordpress.com/2015/03/27/the-simplexmlelement-magic-wonder-world-in-php/ | |
* | |
* @param string $name of the field | |
* | |
* @return null|mixed retrieved value or null if field is not set | |
*/ | |
public function getData($name) | |
{ | |
$element = dom_import_simplexml($this); | |
if (!isset($element->data[$name])) { | |
return null; | |
} | |
return $element->data[$name]; | |
} | |
/** | |
* assign a document that is processed | |
* | |
* this also registers all xpath namespaces | |
* | |
* @param DOMDocument $doc to process | |
*/ | |
public function assignDocument(DOMDocument $doc) | |
{ | |
/** @var self $root */ | |
$root = $this->xpath('/*')[0]; | |
$xpath = new DOMXPath($doc); | |
foreach ($root->xml->namespace as $namespace) { | |
$xpath->registerNamespace($namespace['prefix'], $namespace['uri']); | |
} | |
$root->setData('xpath', $xpath); | |
} | |
public function toArray(DOMNode $context = null) | |
{ | |
/** @var self $root */ | |
$root = $this->xpath('/*')[0]; | |
if ($root == $this) { | |
return $this->array[0]->toArray(); | |
} | |
/** @var DOMXPath $xpath */ | |
$xpath = $root->getData('xpath'); | |
$return = []; | |
foreach ($this as $child) { | |
$result = $evaluated = $xpath->evaluate($child['expr'], $context); | |
if ($evaluated instanceof DOMNodeList) { | |
if (1 === $evaluated->length) { | |
$result = $child->toArray($evaluated->item(0)); | |
} else { | |
$result = []; | |
foreach ($evaluated as $node) { | |
$result[] = $child->toArray($node); | |
} | |
} | |
} | |
$name = (string)($child['alias'] ?: $child->getName()); | |
$return[$name] = $result; | |
} | |
// single elements can be casted to string | |
if ((1 === count($this)) and ('string' === (string)$child['cast'])) { | |
$return = reset($return); | |
} | |
return $return; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi again Hakre! I'm still using your handy script. Would you kindly explain me how can I read the ID attribute of
comma
given for example the following XML?Should'nt be as easy as this:
<comma expr="//comma/@id"/>
The expected result should beart1-com1
I can get the value of
num
for example like this<num expr="normalize-space(string(a:num))"/>
but I don't know how to get the
id
attribute.Thank you.