Page 1 of 1

Converting XML to nested arrays.

Posted: Sat May 05, 2007 10:07 am
by tobyw_1969
feyd | Please use

Code: Select all

,

Code: Select all

and [syntax="..."] tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read:  [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]


Could anyone tell me why this code doesn't work? I'm not a PHP expert, but I am used to other OOP like Java.

I am trying to use the xml_parser function to create a series of nested arrays, allowing me to access elements in an XML file by using simple paths. Eg.

[syntax="xml"]<XML>
<Person>
 <Name>John</Name>
</Person>
</XML>
would be parsed and could then be accessed like this[/syntax]

Code: Select all

$name = $parsedXML['XML']['Person']['Name'];

I am trying to do this by assigning the node name as the key for the array object.

Code: Select all

<?php

function startElementHandler ($parser,$name,$attrib){
	global $xmlObject;
	global $currentObject;
	$child = createChild($currentObject,$name);
	$currentObject[$name] = $child;
	print("<br><hr><br>");
	print_r($currentObject);//
	$currentObject = $currentObject[$name];
}

function endElementHandler ($parser,$name){
	global $xmlObject;
	global $currentObject;
	$currentObject = $currentObject['parent'];
}

function characterDataHandler ($parser, $data) {
	global $xmlObject;
	global $currentObject;
	$currentObject['value'] = $data;
}

function createChild($parent,$childName){
	return array('name'=>$childName,'parent'=>$parent);
}


$xmlObject = array('name'=>'TOP');
$currentObject = $xmlObject;

if (!($fp=@fopen("inputXML.xml", "r"))) die ("Couldn't open XML.");
if (!($xml_parser = xml_parser_create())) die("Couldn't create parser.");
xml_set_element_handler($xml_parser,"startElementHandler","endElementHandler");
xml_set_character_data_handler( $xml_parser, "characterDataHandler");
while( $data = fread($fp, 4096)){
	if(!xml_parse($xml_parser, $data, feof($fp))) {
		break;
	}
}


print("<br><br>XMLOBJECT:");
print_r($xmlObject);
print("COUNT:".count($xmlObject));
This code sort of works. It does seem to get the child-parent relationship right, meaning the right node gets assigned to the right array. But if you look at the output

http://www.netcartoon.net/orgchart/xmlparse.php5

.. it seems to create each array correctly, but then once the routine has finished, the top array is completely blank again.

Sorry if I am being stupid. Does this make sense to anyone, and can you offer any advice?

Thank you very much.


feyd | Please use

Code: Select all

,

Code: Select all

and [syntax="..."] tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read:  [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]

Posted: Sat May 05, 2007 11:21 am
by volka
Is an array mandatory or will

Code: Select all

<?php
error_reporting(E_ALL);

$xmlstring = <<< eox
<XML>
  <Person>
    <Name>John</Name>
  </Person>
</XML>
eox;



$XML = simplexml_load_string($xmlstring);
echo $XML->Person->Name;
suffice?

Posted: Sat May 05, 2007 11:46 am
by timvw

Posted: Sat May 05, 2007 11:47 am
by tobyw_1969
Hi Volka, yes you are right I could just use that.

To be honest, I only found out about simpleXML after posting, and it seems to do what I was trying to create myself (I was using arrays because I wasn't sure if you can create generic objects in PHP and assign dyanmic properties to them).

BUT

I hate to walk away from a problem just because there is an easier way! So I would still love to know what is wrong with my code. It seems like when I try to dynamically create keys they don't persist... It must be possible to do what I was trying to do, and it would be nice to be able to do it myself I guess.

Thanks