[development] development Digest, Vol 99, Issue 69
Karl Giesing
khzmusik at hotmail.com
Fri Mar 25 15:25:54 UTC 2011
> I've tried simplexml and a few third-party scripts, one that loads the > xml into an associative array rather than an object, and nothing lets me > get at 'red' or 'blue'.
I needed something similar for my module. First of all, I wanted it to be compatible with PHP4. This means I needed to use xml_parser functions. Second, I didn't want the user to have to install another module or library.
I ended up using two functions (one is recursive):
/** * Takes an XML string, and returns a multidimensional array. Each "dimension" * may be a text string, a key-value array of tag attributes, and/or another * multidimensional array containing child nodes. * * @param $string * String containing XML data to parse * @return * Multidimensional array with attributes, values, and children */function _discogs_xml_to_array(&$string) { $parser = xml_parser_create(); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); xml_parse_into_struct($parser, $string, $vals, $index); xml_parser_free($parser);
$multi_array = array(); foreach ($vals as $val) { $tag = $val['tag']; if ($val['type'] == 'open') { if (isset($multi_array[$tag])) { if (isset($multi_array[$tag][0])) { $multi_array[$tag][]=array(); } else { $multi_array[$tag]=array($multi_array[$tag], array()); } $cv = &$multi_array[$tag][count($multi_array[$tag])-1]; } else { $cv = &$multi_array[$tag]; } if (isset($val['attributes'])) { foreach ($val['attributes'] as $k => $v) { $cv['_attributes'][$k] = $v; } } $cv['_nodes'] = array(); $cv['_nodes']['_recursion'] = &$multi_array; $multi_array = &$cv['_nodes']; } elseif ($val['type'] == 'complete') { if (isset($multi_array[$tag])) { if (isset($multi_array[$tag][0])) { $multi_array[$tag][] = array(); } else { $multi_array[$tag] = array($multi_array[$tag], array()); } $cv = &$multi_array[$tag][count($multi_array[$tag])-1]; } else { $cv = &$multi_array[$tag]; } if (isset($val['attributes'])) { foreach ($val['attributes'] as $k => $v) { $cv['_attributes'][$k] = $v; } } if (isset($val['value'])) { $cv['value'] = trim($val['value']); } } elseif ($val['type'] == 'close') { $multi_array = &$multi_array['_recursion']; } } // Clean up the recursion and merge attributes with child nodes $multi_array = _discogs_xml_clean($multi_array);
return $multi_array;}
/** * Helper function for _discogs_xml_to_array. * * Cleans up the array structure, by getting rid of the recursive data, and * merging the values, attributes and child nodes. * * @param array $old_array * Old array to clean up * @return array $new_array * Cleaned up array */function _discogs_xml_clean($old_array) { // Double check that it's an array, for recursion if (!is_array($old_array)) { return $old_array; } foreach ($old_array as $k => $v) { if ($k === '_recursion') { unset($old_array[$k]); } elseif (is_array($old_array[$k]['_nodes']) && is_array($old_array[$k]['_attributes'])) { $old_nodes = _discogs_xml_clean($old_array[$k]['_nodes']); $new_merged = array_merge($old_array[$k]['_attributes'], $old_nodes); $new_array[$k] = $new_merged; } elseif (isset($old_array[$k]['value']) && is_array($old_array[$k]['_attributes'])) { $value['value'] = trim($old_array[$k]['value']); $new_merged = array_merge($old_array[$k]['_attributes'], $value); $new_array[$k] = $new_merged; } elseif (is_array($old_array[$k]['_nodes'])) { $new_array[$k] = _discogs_xml_clean($old_array[$k]['_nodes']); } elseif (isset($old_array[$k]['_attributes'])) { $new_array[$k] = $old_array[$k]['_attributes']; } elseif (isset($old_array[$k]['value'])) { $new_array[$k] = $old_array[$k]['value']; } else { $old_nodes = _discogs_xml_clean($old_array[$k]); $new_array[$k] = $old_nodes; } } return $new_array;}
So, if you passed your XML file to the first function, this would be the resulting multidimensional array:
Array( [this] => Array ( [that] => Array ( [0] => Array ( [parm1] => a [parm2] => b [parm3] => c [value] => red )
[1] => Array ( [parm1] => e [parm2] => f [parm3] => d [value] => blue ) ) ))
It's complicated, but it works.
-Karl.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.drupal.org/pipermail/development/attachments/20110325/70cc9136/attachment-0001.html
More information about the development
mailing list