-
-
Save hakre/c36a66708259f54e564a to your computer and use it in GitHub Desktop.
<?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; | |
} | |
} |
In your example the string "Lorem ipsum...
" is the first text-child-node of the corpo element. It's no problem to retrieve it. When you're looking for the XML of the table, this would require returning the inner-XML which needs a modification. Xpath on it's own does not have a method to retrieve it, but the class could be extended to deal with it, perhaps similar as with the cast parameter.
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?
<articolato>
<articolo id="art1">
<num>Art. 1</num>
<comma id="art1-com1">
<corpo>Blah blah blah</corpo>
</comma>
</articolo>
</articolato>
Should'nt be as easy as this:
<comma expr="//comma/@id"/>
The expected result should be art1-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.
Thanks to your excellent script I can read a complex XML and extract only the strings as wished. I noticed that sometimes the XML contains tables as the following. In these cases, with your script, can I somehow read both the string "Lorem ipsum..." and the HTML table keeping the tags?