note 20412 added to function.xml-parse-into-struct

From: Date: Wed, 03 Apr 2002 08:32:08 +0000
Subject: note 20412 added to function.xml-parse-into-struct
Groups: php.notes 
Request: Send a blank email to php-notes+get-28529@lists.php.net to get a copy of this message
Here is another variation on gdemartini@bol.com.br's nice tree algorithm. I have included nyk@cowham.net's "cdata" suggestion. I made a few changes to suppress unitialized variable warnings with error_reporting(E_ALL), and made a few stylistic changes. There are two functional modifications as well. The first is the added option to expat to turn off "case folding", since XML is technically a case-sensitive language. The second is the returned tree - instead of returning a single-element list (an array with index 0 pointing to the top node) like the original algorithm, it returns the top node itself. This saves you an unnecessary level of indirection. function xml_get_children($vals, &$i) { $children = array(); if (isset($vals[$i]['value'])) $children[] = $vals[$i]['value']; while (++$i < count($vals)) { switch ($vals[$i]['type']) { case 'cdata': $children[] = $vals[$i]['value']; break; case 'complete': $children[] = array( 'tag' => $vals[$i]['tag'], 'attributes' => isset($vals[$i]['attributes'])? $vals[$i]['attributes'] : null, 'value' => $vals[$i]['value'], ); break; case 'open': $children[] = array( 'tag' => $vals[$i]['tag'], 'attributes' => isset($vals[$i]['attributes'])? $vals[$i]['attributes'] : null, 'children' => xml_get_children($vals, $i), ); break; case 'close': return $children; } } } function xml_get_tree($file) { $data = join('', file($file)); $parser = xml_parser_create(); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); xml_parse_into_struct($parser, $data, $vals, $index); xml_parser_free($parser); return array( 'tag' => $vals[0]['tag'], 'attributes' => isset($vals[0]['attributes'])? $vals[0]['attributes'] : null, 'children' => xml_get_children($vals, $i = 0), ); } This function takes a tree returned by xml_get_tree() and simplifies it similarly to voncken@mailandnews.com and oknapp@soly.de's suggestions. It finds any nodes that expat considered "complete" (childless) and contain no attributes, and it moves the tag name (as the key) and value into an element in the parent node's "values" array. For example: $tree = xml_get_tree('moldb.xml'); $tree = xml_condense_tree($tree); echo $tree['children'][1]['values']['name']; Outputs: Lysine function xml_condense_tree($tree) { foreach ($tree['children'] as $index => $node) { if (isset($node['children'])) { $tree['children'][$index] = xml_condense_tree($node); } elseif (isset($node['value']) and !$node['attributes']) { $tree['values'][$node['tag']] = $node['value']; unset($tree['children'][$index]); } } if (!$tree['children']) unset($tree['children']); return $tree; } Enjoy, Dave -- http://www.php.net/manual/en/function.xml-parse-into-struct.php http://master.php.net/manage/user-notes.php?action=edit+20412 http://master.php.net/manage/user-notes.php?action=delete+20412 http://master.php.net/manage/user-notes.php?action=reject+20412

« previous php.notes (#28529) next »