Last active
September 10, 2015 17:11
-
-
Save garvin/1a31fa8c4b707330b941 to your computer and use it in GitHub Desktop.
Two functions to convert an XML document to an array using SimpleXML.
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 | |
/** | |
* Convert a SimpleXMLElement to an associative array. | |
* | |
* Note: ignores attributes. | |
* | |
* @param SimpleXMLElement $sxe A SimpleXMLElement. | |
* @param array $repeating_elements A array of names of elements that repeat. Optional. | |
* @return mixed Returns null when the element is empty/doesn't exist. | |
* Otherwise returns a nested associative array of this | |
* element's children & their values, i.e.: | |
* array( | |
* 'child1name' => 'child1value', | |
* 'child2name' => array( | |
* 'child2grandchild1name' => 'child2grandchild1value', | |
* 'child2grandchild2name' => 'child2grandchild2value', | |
* // etc... | |
* ) | |
* // etc... | |
* ) | |
*/ | |
function simplexml_to_array($sxe, $repeating_elements = array()) { | |
// ensure $repeating_elements is an array & not null | |
$repeating_elements = is_array($repeating_elements) ? $repeating_elements : array(); | |
$a = array(); | |
// we could have gotten an object or array | |
if (is_object($sxe)) { | |
$sxe = get_object_vars($sxe); | |
/* If it was an empty/no property object, it will be converted by | |
* get_object_vars into an empty array. It should be null. */ | |
if (empty($sxe)) { | |
return null; | |
} | |
} | |
foreach($sxe as $key => $value) { | |
if (is_object($value) || is_array($value)) { | |
$a[$key] = simplexml_to_array($value); | |
/* simplexml_to_array() has a quirk we have to compensate for here. | |
* | |
* When $key is a repeater, but $a[$key] doesn't have an [0] index, | |
* we need to make $a[$key] = array($a[$key]) so that $a[$key] is | |
* always an array of [the repeating subelements]. It's annoying. */ | |
if (in_array($key, $repeating_elements) && !isset($a[$key][0])) { | |
$a[$key] = array($a[$key]); | |
} | |
} else { | |
$a[$key] = $value; | |
} | |
} | |
return $a; | |
} | |
/** | |
* Parse a(n?) XML document and convert its body into an associative array. | |
* | |
* Example | |
* ------- | |
* If $xml is: | |
* | |
* <?xml version="1.0" encoding="UTF-8"?> | |
* <envelope | |
* xmlns="http://www.example.org" | |
* xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
* xsi:schemaLocation="http://www.example.org | |
* stooge.xsd" | |
* > | |
* <body> | |
* <stooges> | |
* <moe>Oh, a wise guy, eh?</moe> | |
* <larry>Hey, what's the big idea?</larry> | |
* <curly>Nyuknyuknyuk!</curly> | |
* <alternates> | |
* <shemp>Oh...I'm shot! Or I'm half shot, I wanna be shot...Oh, I guess I'll have a shot.</shemp> | |
* <joe>Oh, cut it ouuuuuut!</joe> | |
* <curly_joe>One of these days, you're gonna poke my eyes out.</curly_joe> | |
* </alternates> | |
* <effects> | |
* <effect>smack!</effect> | |
* <effect>bonk!</effect> | |
* <effect>boing!</effect> | |
* </effects> | |
* </stooges> | |
* </body> | |
* </envelope> | |
* | |
* This is what would be returned: | |
* | |
* $xml_data = array( | |
* 'stooges' => array( | |
* 'moe' => 'Oh, a wise guy, eh?', | |
* 'larry' => 'Hey, what's the big idea?', | |
* 'curly' => 'Nyuknyuknyuk!', | |
* 'alternates' => array( | |
* 'shemp' => 'Oh...I'm shot! Or I'm half shot, I wanna be shot...Oh, I guess I'll have a shot.', | |
* 'joe' => 'Oh, cut it ouuuuuut!', | |
* 'curly_joe' => 'One of these days, you're gonna poke my eyes out.', | |
* ), | |
* ) | |
* ); | |
* | |
* @see simplexml_load_string() | |
* @see simplexml_to_array() | |
* @param string $xml A well-formed XML document (simplexml_load_string will accept no other). | |
* @return array The body of the request as an array. On error, returns an empty array. | |
*/ | |
function &simplexml_load_array(&$xml) { | |
$xml = simplexml_load_string($xml); | |
// verify parsing went OK | |
if (empty($xml)) { | |
return array(); | |
} | |
/* Convert the object simplexml_load_string gave us to an array. Obviously | |
* it would need a 'body'. */ | |
$xml_data = simplexml_to_array($xml->body); | |
if (!$xml_data) { | |
// Still OK to error & exit at this point. Same reason. | |
return array(); | |
} | |
return $xml_data; | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment