<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Tahoma
}
--></style>
</head>
<body class='hmmessage'>
<div><font class="Apple-style-span" face="Tahoma" size="2"><div>> I've tried simplexml and a few third-party scripts, one that loads the </div><div>> xml into an associative array rather than an object, and nothing lets me </div><div>> get at 'red' or 'blue'. </div><div><br></div><div>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.</div><div><br></div><div>I ended up using two functions (one is recursive):</div><div><br></div><div>/**</div><div> * Takes an XML string, and returns a multidimensional array. Each "dimension"</div><div> * may be a text string, a key-value array of tag attributes, and/or another</div><div> * multidimensional array containing child nodes.</div><div> *</div><div> * @param $string</div><div> * String containing XML data to parse</div><div> * @return</div><div> * Multidimensional array with attributes, values, and children</div><div> */</div><div>function _discogs_xml_to_array(&$string) {</div><div> $parser = xml_parser_create();</div><div> xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);</div><div> xml_parse_into_struct($parser, $string, $vals, $index);</div><div> xml_parser_free($parser);</div><div><br></div><div> $multi_array = array();</div><div> foreach ($vals as $val) {</div><div> $tag = $val['tag'];</div><div> if ($val['type'] == 'open') {</div><div> if (isset($multi_array[$tag])) {</div><div> if (isset($multi_array[$tag][0])) {</div><div> $multi_array[$tag][]=array();</div><div> }</div><div> else {</div><div> $multi_array[$tag]=array($multi_array[$tag], array());</div><div> }</div><div> $cv = &$multi_array[$tag][count($multi_array[$tag])-1];</div><div> }</div><div> else {</div><div> $cv = &$multi_array[$tag];</div><div> }</div><div> if (isset($val['attributes'])) {</div><div> foreach ($val['attributes'] as $k => $v) {</div><div> $cv['_attributes'][$k] = $v;</div><div> }</div><div> }</div><div> $cv['_nodes'] = array();</div><div> $cv['_nodes']['_recursion'] = &$multi_array;</div><div> $multi_array = &$cv['_nodes'];</div><div> }</div><div> elseif ($val['type'] == 'complete') {</div><div> if (isset($multi_array[$tag])) {</div><div> if (isset($multi_array[$tag][0])) {</div><div> $multi_array[$tag][] = array();</div><div> }</div><div> else {</div><div> $multi_array[$tag] = array($multi_array[$tag], array());</div><div> }</div><div> $cv = &$multi_array[$tag][count($multi_array[$tag])-1];</div><div> }</div><div> else {</div><div> $cv = &$multi_array[$tag];</div><div> }</div><div> if (isset($val['attributes'])) {</div><div> foreach ($val['attributes'] as $k => $v) {</div><div> $cv['_attributes'][$k] = $v;</div><div> }</div><div> }</div><div> if (isset($val['value'])) {</div><div> $cv['value'] = trim($val['value']);</div><div> }</div><div> }</div><div> elseif ($val['type'] == 'close') {</div><div> $multi_array = &$multi_array['_recursion'];</div><div> }</div><div> }</div><div><div> // Clean up the recursion and merge attributes with child nodes</div><div> $multi_array = _discogs_xml_clean($multi_array);</div></div><div><br></div><div> return $multi_array;</div><div>}</div><div><br></div><div>/**</div><div> * Helper function for _discogs_xml_to_array.</div><div> *</div><div> * Cleans up the array structure, by getting rid of the recursive data, and</div><div> * merging the values, attributes and child nodes.</div><div> *</div><div> * @param array $old_array</div><div> * Old array to clean up</div><div> * @return array $new_array</div><div> * Cleaned up array</div><div> */</div><div>function _discogs_xml_clean($old_array) {</div><div> // Double check that it's an array, for recursion</div><div> if (!is_array($old_array)) {</div><div> return $old_array;</div><div> }</div><div> foreach ($old_array as $k => $v) {</div><div> if ($k === '_recursion') {</div><div> unset($old_array[$k]);</div><div> }</div><div> elseif (is_array($old_array[$k]['_nodes']) && is_array($old_array[$k]['_attributes'])) {</div><div> $old_nodes = _discogs_xml_clean($old_array[$k]['_nodes']);</div><div> $new_merged = array_merge($old_array[$k]['_attributes'], $old_nodes);</div><div> $new_array[$k] = $new_merged;</div><div> }</div><div> elseif (isset($old_array[$k]['value']) && is_array($old_array[$k]['_attributes'])) {</div><div> $value['value'] = trim($old_array[$k]['value']);</div><div> $new_merged = array_merge($old_array[$k]['_attributes'], $value);</div><div> $new_array[$k] = $new_merged;</div><div> }</div><div> elseif (is_array($old_array[$k]['_nodes'])) {</div><div> $new_array[$k] = _discogs_xml_clean($old_array[$k]['_nodes']);</div><div> }</div><div> elseif (isset($old_array[$k]['_attributes'])) {</div><div> $new_array[$k] = $old_array[$k]['_attributes'];</div><div> }</div><div> elseif (isset($old_array[$k]['value'])) {</div><div> $new_array[$k] = $old_array[$k]['value'];</div><div> }</div><div> else {</div><div> $old_nodes = _discogs_xml_clean($old_array[$k]);</div><div> $new_array[$k] = $old_nodes;</div><div> }</div><div> }</div><div> return $new_array;</div><div>}</div><div><br></div><div>So, if you passed your XML file to the first function, this would be the resulting multidimensional array:</div><div><br></div><div>Array</div><div>(</div><div> [this] => Array</div><div> (</div><div> [that] => Array</div><div> (</div><div> [0] => Array</div><div> (</div><div> [parm1] => a</div><div> [parm2] => b</div><div> [parm3] => c</div><div> [value] => red</div><div> )</div><div><br></div><div> [1] => Array</div><div> (</div><div> [parm1] => e</div><div> [parm2] => f</div><div> [parm3] => d</div><div> [value] => blue</div><div> )</div><div> )</div><div> )</div><div>)</div><div><br></div><div>It's complicated, but it works.</div><div><br></div><div>-Karl.</div></font></div>                                            </body>
</html>