-
-
Save jasondmoss/7344311 to your computer and use it in GitHub Desktop.
| <?php | |
| /** | |
| * Convert a SimpleXML object to an associative array | |
| * | |
| * @param object $xmlObject | |
| * | |
| * @return array | |
| * @access public | |
| */ | |
| function simpleXmlToArray($xmlObject) | |
| { | |
| $array = []; | |
| foreach ($xmlObject->children() as $node) { | |
| $array[$node->getName()] = is_array($node) ? simplexml_to_array($node) : (string) $node; | |
| } | |
| return $array; | |
| } |
Hi all, in the end, I used following from https://hotexamples.com/examples/-/-/simplexml_to_array/php-simplexml_to_array-function-examples.html, with some edits.
/** * @param $xml * @return array * https://hotexamples.com/examples/-/-/simplexml_to_array/php-simplexml_to_array-function-examples.html */ public static function simplexmlToArray($xml) { $ar = array(); foreach ($xml->children() as $k => $v) { $child = self::simplexmlToArray($v); if (count($child) == 0) { $child = (string) $v; } foreach ($v->attributes() as $ak => $av) { if (!is_array($child)) { $child = array("value" => $child); } $child[$ak] = (string) $av; } if (!array_key_exists($k, $ar)) { $ar[$k] = $child; } else { if (!is_string($ar[$k]) && isset($ar[$k][0])) { $ar[$k][] = $child; } else { $ar[$k] = array($ar[$k]); $ar[$k][] = $child; } } } return $ar; }
This worked great, even on my XML that had many sub nodes.
Hi all, in the end, I used following from https://hotexamples.com/examples/-/-/simplexml_to_array/php-simplexml_to_array-function-examples.html, with some edits.
/** * @param $xml * @return array * https://hotexamples.com/examples/-/-/simplexml_to_array/php-simplexml_to_array-function-examples.html */ public static function simplexmlToArray($xml) { $ar = array(); foreach ($xml->children() as $k => $v) { $child = self::simplexmlToArray($v); if (count($child) == 0) { $child = (string) $v; } foreach ($v->attributes() as $ak => $av) { if (!is_array($child)) { $child = array("value" => $child); } $child[$ak] = (string) $av; } if (!array_key_exists($k, $ar)) { $ar[$k] = $child; } else { if (!is_string($ar[$k]) && isset($ar[$k][0])) { $ar[$k][] = $child; } else { $ar[$k] = array($ar[$k]); $ar[$k][] = $child; } } } return $ar; }
That works like a charm. Thanks!
I refactored it to be more readable -> tested on php 8.3 + changed how attributes are stored
/**
* Converts a SimpleXMLElement object to an associative array.
*/
public static function simpleXmlToArray(?SimpleXMLElement $xml): array|string {
if ($xml === null) {
return [];
}
$result = [];
foreach ($xml->attributes() as $attrName => $attrValue) {
$result['@attributes'][$attrName] = (string) $attrValue;
}
foreach ($xml->children() as $childName => $childElement) {
$childArray = self::simpleXmlToArray($childElement);
if (!isset($result[$childName])) {
$result[$childName] = $childArray;
continue;
}
if (!is_array($result[$childName]) || !array_is_list($result[$childName])) {
$result[$childName] = [$result[$childName]];
}
$result[$childName][] = $childArray;
}
$textContent = trim((string) $xml);
if (empty($result)) {
return $textContent;
}
if ($textContent !== '') {
$result['@value'] = $textContent;
}
return $result;
}
Thanx @Harfusha , saved me lot of time !
Will this give the expected result?
json_decode(json_encode($xml), true);
For the most part this worked for me, but I found some instances maybe 5 levels in that had CDATA content and were simply converted to an empty array.
Thanks everyone for chipping in to this simple little snippet (which worked for my purpose at the time). I mainly just use Gists as 'notes to self'. This has just kept growing :) Great job.
This one did work for me (saw a similar line online) as it kept the inner XML so they ended up being blank