A while ago I wrote a XML parser based on some stuff I found here, but it never produced a 100% satisfying result. So today I wrote a new one - maybe it might be handy for someone, it’s generic.
At first, what it actually does is parsing your whole xml in a multi-layered array. The only downside is that you can’t use the same element-name twice in the same node-level, since you can’t give your array key the same name twice in the same level.
The result is dead-simple to work with. In the example I split my xml’s in 2 arrays, one containing the nodevalues and the other the attributes (of course you can simply alter the code to 1 all-containing array) :
<?xml version="1.0" encoding="windows-1252"?>
<siteContent>
<main nme='foo' id='bar'>
<sub nme='fooSub' id='barSub'>Hello world</sub>
</main>
</siteContent>
//PHP result:
echo $XMLatr['main']['nme'];
// prints 'foo'
echo $XMLval['main']['sub'];
// prints 'Hello world'
As you can see, very simple and ‘human-readable’. The code to do this is short and handy. Just include the xmlParse.php file, and you’re set.
The document where you output the xml data:
// XML Parser
$file = "some-xml.xml";
include 'xmlParse.php';
// example output
echo $XMLval['foo']['bar'];
The xmlParse.php file:
$XMLval=$XMLatr=$depth=array();
$n=0; $str='';
// XML parse Functions
function startElement($parsn, $name, $attrs){
global $n, $depth, $XMLval, $XMLatr, $str;
if($n>0){
$depth[$n]=$name; $str='';
for($a=1;$a<=$n;$a++)$str.='["'.$depth[$a].'"]';
if($attrs)eval("\$XMLatr".$str."=\$attrs;");
}; $n++;
}
function characterData($parsn, $nodeval){
global $str, $XMLval;
if(strlen(rtrim($nodeval,"
\r")))eval("\$XMLval".$str."=\$nodeval;");
}
function endElement($parsn, $name){
global $n; $n--;
}
// PARSE!
$xml_parser = xml_parser_create();
xml_parser_set_option($xml_parser,XML_OPTION_SKIP_WHITE,1);
xml_parser_set_option($xml_parser,XML_OPTION_CASE_FOLDING,0);
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");
if (!($fp = fopen($file, "r"))) {
die("could not open XML input");
}
while ($data = fread($fp, 4096)) {
if (!xml_parse($xml_parser, $data, feof($fp))) {
die(sprintf("XML error: %s at line %d",
xml_error_string(xml_get_error_code($xml_parser)),
xml_get_current_line_number($xml_parser)));
}
}
xml_parser_free($xml_parser);
fclose($fp);
You can use this on unlimited deep xml.
If you want an example containing all xml data into a single array, let me know.