trouble parsing xml - object properties being lost!

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
tomfumb
Forum Newbie
Posts: 1
Joined: Mon Aug 25, 2008 4:16 pm

trouble parsing xml - object properties being lost!

Post by tomfumb »

Hi, thanks for looking.

I recently started working with xml in php and started doing it the easy way - using simplexml functions in php5. I then discovered that my web hosting providers only provide php4, and so I have to change to use the full-blown xml parsing functions.

I've read loads of examples of how to create a parser object, recognise start and end tags etc. to do something simple like indent xml-sourced data in html, but I need to parse xml and return an array of objects (in a separate php script included in a number of pages).

It seems that the functions called by the xml parser (i.e. start_tag, end_tag, tag_contents) don't really 'know' about the array and its objects that I'm trying to work with. Here is my code:

Code: Select all

 
<?php
 
function parseObjectXML($xmlPath,$objCount) {
 
        // populate the array I need to return
    $internalObjArray = array();
    for($x = 0; $x < $objCount; $x++)   {
        $thisObj = new FatBiscuitObject();
        array_push($internalObjArray,$thisObj);
        }
    $current = "";
 
    if (! ($xmlparser = xml_parser_create()) )  { 
        die ("Cannot create parser");
        }
 
    function start_tag($parser, $name, $attribs)    {
        global $current;
        $current = $name;
        if ($name == "TYPE") {
                        // currently nothing in here
            }
        }
 
    function end_tag($parser, $name)    {
        if ($name == "SOURCE") {
                        // currently nothing in here
            }
        }
 
    function tag_contents($parser, $data)   {
        global $current;
        global $internalObjArray;
 
        switch($current)    {
            case "TYPE": 
                $internalObjArray[count($internalObjArray)]->type = $data;
                break;
            case "ID":
                $internalObjArray[count($internalObjArray)]->id = $data;
                break;
            case "NAME":
                $internalObjArray[count($internalObjArray)]->name = $data;
                break;
            case "DESCRIPTION":
                $internalObjArray[count($internalObjArray)]->description = $data;
                break;
            /*... and so on */
            }
        }
 
    xml_set_element_handler($xmlparser, "start_tag", "end_tag");
    xml_set_character_data_handler($xmlparser, "tag_contents");
 
    $filename = $xmlPath;
    if (!($fp = fopen($filename, "r"))) { die("cannot open ".$filename); }
 
    while ($data = fread($fp, 4096))    {
        $data=eregi_replace(">"."[[:space:]]+"."<","><",$data);
        if (!xml_parse($xmlparser, $data, feof($fp)))   {
                $reason = xml_error_string(xml_get_error_code($xmlparser));
                $reason .= xml_get_current_line_number($xmlparser);
                die($reason);
            }
        }
 
    xml_parser_free($xmlparser);
 
        // report what's in the array's objects
    echo "count: ".count($internalObjArray)."<br />0->ID: ".$internalObjArray[0]->id."<br />0->Name: ".$internalObjArray[0]->name;
    return $internalObjArray;
}
 
?>
 
The output of the second to last line looks like this:

Code: Select all

 
count: 2
0->ID:
0->Name: 
 
So the 'FatBiscuitObject' objects are in the array, but nothing is being assigned in the 'tag_contents' function. Through testing it is clear that the right xml tags are being picked up, and that the 'tag_contents' function is working as expected, except it's obviously not permenantly assigning object properties.

In the code above I'm assigning the number of objects I expect to find contained within the xml up-front. I'd rather push the completed object into the array when I come across the closing tag 'SOURCE', but if I do I am told that the $internalObjArray does not exist... As far as I can see this is not a problem with how I am referencing global variables as the $current variable is used as expected.

It seems that the 'tag_contents' function simply doesn't know about the $internalObjArray array, and therefore assigns nothing.

Any suggestions / help with this would be massively appreciated as I am about to give up completely due to lack of progress.
marcth
Forum Contributor
Posts: 142
Joined: Mon Aug 25, 2008 8:16 am

Re: trouble parsing xml - object properties being lost!

Post by marcth »

Creating an proper XML parser would require a tremendous amount of time. I'd humbly suggest:
  • Not using XML
  • Changing Hosts that use PHP5 (PHP4 is nearly obsolete)
  • Using an existing open-source solution to parse your XML under PHP 4
I apologize if this isn't the answer you were looking for.

Regards,
Post Reply