Last Updated: February 25, 2016
·
1.153K
· tlackemann

A little more than simpleXML hack

Suppose you have the following xml file

<?xml version="1.0" ?>
<parent>
 <child>
 Some text
 <sub>more text</sub>
 continued text
 </child>
</parent>

Using SimpleXML gives you a result like this

SimpleXMLElement Object
(
 [child] =>
Some text

continued text
)

Weird. I wrote a quick hack to get around this. Comments welcome.

function parseXML($xml) {
 $xr = new XMLReader();
 $xr->open($xml);

 # Set variables for loop
 $array = array();
 $openParentNode = false;
 $openChildNode = false;
 $setNode = null;
 $parentNode = 'parent';
 $triggerNodes = array('child');

 while($xr->read()) {
 # If we hit the "parent" node, open it
 if ($xr->name == $parentNode && !$openParentNode) {
 $i = count($array);
 $openParentNode = true;
 $setNode = $parentNode;
 $array[$i][$parentNode] = array();
 } elseif ($xr->name == $parentNode && $openParentNode) {
 $openParentNode = false;
 $setNode = null;
 }

 # If the "parent" is open, process the title parameters
 if ($openParentNode && (in_array($xr->name, $triggerNodes) || $xr->nodeType == XMLReader::TEXT)) {
 # If one of the trigger nodes is hit, open it
 if (in_array($xr->name, $triggerNodes) && $xr->name != $setNode) {
 $openChildNode = true;
 $setNode = $xr->name;
 } elseif (in_array($xr->name, $triggerNodes) && $xr->name == $setNode) {
 $openChildNode = false;
 $setNode = $parentNode;
 }

 # Text node - throw it into the array
 if ($openChildNode && $xr->nodeType == XMLReader::TEXT) {
 $array[$i][$parentNode][$setNode] = (isset($array[$i][$parentNode][$setNode])) ? $array[$i][$parentNode][$setNode].$xr->value : $xr->value;
 }
 }
 }

 return $array;
 }