<?php
/*
        (c) 2000 Hans Anderson Corporation.  All Rights Reserved.
        You are free to use and modify this class under the same
        guidelines found in the PHP License.
        -----------
        bugs/me:
        http://www.hansanderson.com/php/
         [email protected]
        -----------
        YOU NEED PHP4 FOR THIS -- even if you have XML support in PHP3
        (sorry, I hate that, too, but I use some other PHP4 functionality)
        -----------
        What class.xml.php is:
        A very, very easy to use XML parser class. It uses PHP's XML functions
        for you, returning all the objects in the XML file in an easy to use
        Tree.  It also can be used as a statistics-type program, as you can
        use the size() method to find out how many of each elements there are.
        -----------
        Sample use:
        require('class.xml.php');
        $file = "somexmldata.xml";
        $data = implode("",file($file)) or die("could not open XML input file");
        $xml = new xml($data);
        for($i=0;$i<$xml_item_url->size();$i++) {
         print $xml_item_url->get($i) . "\n\n";
        }
        (that's it! slick, huh?)
        -----------
        Two ways to call: 
                $xml = new xml($data);
                - or -
                $xml = new xml($data,"jellyfish");
        The second argument (jellyfish) is optional.  Default is 'xml'.
        if you have 
        "<html><head><title>Title stuff</title></head></html>"
        the object you get would look like this:
        $xml_html_head_title (value is "Title stuff")
        but if you created the object like 
                $xml = new xml($data,"jellyfish");
        then your object would look like this:
        $jellyfish_html_head_title (value is "Title stuff")
        Comprende?  It's only really needed if you want something else to 
        start off your object names.  If you don't understand this, just
        call it like $xml = new xml($data);
        ----------
        Class Methods You Will Use:
        where 'classname' is the name of an XML object, like xml_head_title
        classname->get($idx);
         - returns array item found at $idx
        classname->size();
         - returns the size of the storage array
        -----------
        Explanation:
        This class takes valid XML data as an argument and 
        returns all the information in a concise little
        tree of objects.
        Here's how it works:
                Data:
                        <html>
                         <head>
                          <title>Hans Anderson's XML Class</title>
                         </head>
                         <body>
                         </body>
                        </html>
                Run the data through my class, then access the title like this:
                $xml_html_head_title->get(0);
                That is an object, but you don't have to worry about
                contructing it.  The data is stored in an array in the 
                object, so the ->get(0) is a way to get the data out.  If
                there were more than one item, you'd do a loop just like 
                any array:
                for($i=0;$i<$xml_html_head_title->size();$i++) {
                        print $xml_html_head_title->get($i) . "\n";
                }
                Yes, the variable names *are* long, but it's the best
                way to create the tree, IMO.
                -----------
                Errors:
                if you get the error "Fatal error: Call to a member function on a non-object",
                you have misspelled the name of the XML tags, or you have the case wrong.
*/
class stor {
        var $a; // holds data
                function add($data) {
                        $this->a[] = $data;
                }
                function get($idx) {
                        return $this->a[$idx];
                }
                function size() {
                        return sizeof($this->a);
                }
} // end class stor;
class xml { 
        // initialize some variables
        var $identifier='xml';
        var $current_tag='';
        var $separator='_x_';
        var $delimiter='_';
        var $xml_parser;
        /* Here are the XML functions needed by expat */
        function startElement($parser, $name, $attrs) {
                // global current tag, separator, tagdata?
                $this->current_tag .= $this->separator . $name;
                if(count($attrs)>0) $this->tagdata = $attrs;
        }
        function endElement($parser, $name) {
                //global $current_tag, $tagdata, $separator ?
                $curtag = $this->identifier . str_replace($this->separator,$this->delimiter,$this->current_tag);
                if(!is_array($this->tagdata)) $this->tagdata = trim($this->tagdata);
                if($this->tagdata) {
                        
                        if(is_object($GLOBALS["$curtag"])) {
                                $GLOBALS["$curtag"]->add($this->tagdata);
                        } else {
                                $GLOBALS["$curtag"] = new stor; 
                                $GLOBALS["$curtag"]->add($this->tagdata);
                        }
                } else {
                        // if there is no cdata, we still stor something
                        // in the array, so we can count the levels later
                        if(is_object($GLOBALS["$curtag"])) {
                                $GLOBALS["$curtag"]->add(FALSE);
                        } else {
                                $GLOBALS["$curtag"] = new stor; 
                                $GLOBALS["$curtag"]->add(FALSE);
                        }
                }
                // overwrite curtag, no longer needing the old one
                $curtag = strrev($this->current_tag);
                $curtag = substr($curtag,strpos($curtag,$this->separator)+strlen($this->separator));
                $curtag = strrev($curtag);
                $this->current_tag = $curtag;
                $this->tagdata = '';
                return TRUE;
        }
        function characterData($parser, $cdata) {
                $this->tagdata .= $cdata;
        }
        // this is automatically called when the class is initialized
        function xml($data,$identifier='xml') {  
                $this->identifier = $identifier;
                // are we using php4 or better?
                //print phpversion();
                // create parser object
                $this->xml_parser = xml_parser_create();
                // set up some options and handlers
                xml_set_object($this->xml_parser,$this);
                xml_parser_set_option($this->xml_parser,XML_OPTION_CASE_FOLDING,0);
                xml_set_element_handler($this->xml_parser, "startElement", "endElement");
                xml_set_character_data_handler($this->xml_parser, "characterData");
                if (!xml_parse($this->xml_parser, $data, TRUE)) {
                        die(sprintf("XML error: %s at line %d",
                        xml_error_string(xml_get_error_code($this->xml_parser)),
                        xml_get_current_line_number($this->xml_parser)));
                }
                // we are done with the parser, so let's free it
                xml_parser_free($this->xml_parser);
        }
} // thus, we end our class xml
?>
 
  |