Skip to content

Instantly share code, notes, and snippets.

@garvin
Last active September 10, 2015 17:11
Show Gist options
  • Save garvin/1a31fa8c4b707330b941 to your computer and use it in GitHub Desktop.
Save garvin/1a31fa8c4b707330b941 to your computer and use it in GitHub Desktop.
Two functions to convert an XML document to an array using SimpleXML.
<?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