<?php

// IBExpertWebForms
// copyright  ©  2006-2008 Holger Klemt hklemt@ibexpert.biz
// www.ibexpert.com

//######################################################################
class XMLToArray {

    //----------------------------------------------------------------------
    // private variables
    var $parser;
    var $node_stack = array();

    function get_xml($root_node)
    {
      $tab="";

      function get_values($folder,$parent)
      {
        global $tab;

        $lasttab=$tab;

        $tab=$tab."<span style='font-weight:normal;'>".$parent."</span></td><td>";

        $keys=array_keys($folder);

        echo "<tr style='color:red; font-weight:bold; background-color:#d0d0d0;' valign='top'>";
        echo "<td>";
        echo $tab.$folder['_NAME'];
        echo "</td>";
        echo "<td>";

        echo "<table style='font-family:Arial; font-size:11px;'>";
        for($i=0;$i<count($keys);$i++)
        {
          if($keys[$i]<>"_NAME" && $keys[$i]<>"_ELEMENTS")
          {
            if($keys[$i]=="_DATA" && $folder[$keys[$i]])
            {
              $value=base64_decode($folder[$keys[$i]]);
              echo "<tr><td><span style='color:blue'>".$keys[$i]." (base64-decode)</span></td><td><span style='color:green'>\"".$value."\"</span></td></tr>";
              $value=$folder[$keys[$i]];
            }
            else
              $value=$folder[$keys[$i]];

            if($vkeys=@array_keys($value))
            {
              $kvalue=" (".implode(";",$vkeys).")";
            }

            if($value)
              echo "<tr><td><span style='color:blue'>".$keys[$i]."</span></td><td><span style='color:green'>".$value."</span><span>".$kvalue."</span></td></tr>";
            else
              echo "<tr><td><span style='color:#a0a0a0'>".$keys[$i]."</span></td></tr>";
          }
        }
        echo "</table>";

        echo "</td></tr>";


        if($folder["_ELEMENTS"])
        {
          $sub_drive=$folder["_ELEMENTS"];
          foreach ($sub_drive as $sub_folder)
            get_values($sub_folder,$folder["_NAME"]);
        }
        $tab=$lasttab;
      }

      echo "<table border='0' cellpadding='4' cellspacing='1' style='font-family:Arial; font-size:11px; background-color:#808080;'>";

      get_values($root_node,"");

      echo "</table>";
    }
    //----------------------------------------------------------------------
    /** PUBLIC
     * If a string is passed in, parse it right away.
     */
    function XMLToArray($xmlstring="") {
        if ($xmlstring) return($this->parse($xmlstring));
        return(true);
    }

    //----------------------------------------------------------------------
    /** PUBLIC
     * Parse a text string containing valid XML into a multidimensional array
     * located at rootnode.
     */
    function parse($xmlstring="") {
        // set up a new XML parser to do all the work for us
        $this->parser = xml_parser_create();
        xml_set_object($this->parser, $this);
        xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false);
        xml_set_element_handler($this->parser, "startElement", "endElement");
        xml_set_character_data_handler($this->parser, "characterData");

        // Build a Root node and initialize the node_stack...
        $this->node_stack = array();
        $this->startElement(null, "root", array());

        // parse the data and free the parser...
        xml_parse($this->parser, $xmlstring);
        xml_parser_free($this->parser);

        // recover the root node from the node stack
        $rnode = array_pop($this->node_stack);

        // return the root node...
        return($rnode);
    }

    //----------------------------------------------------------------------
    /** PROTECTED
     * Start a new Element.  This means we push the new element onto the stack
     * and reset it's properties.
     */
    function startElement($parser, $name, $attrs) {
        // create a new node...
        $node = array();
        $node["_NAME"]      = $name;
        foreach ($attrs as $key => $value) {
            $node[$key] = $value;
        }
        $node["_DATA"]      = "";
        $node["_ELEMENTS"]  = array();

        //$count=count($this->node_stack);

        //$node[$name]        = &$node["_ELEMENTS"];

        // add the new node to the end of the node stack
        array_push($this->node_stack, $node);
    }

    //----------------------------------------------------------------------
    /** PROTECTED
     * End an element.  This is done by popping the last element from the
     * stack and adding it to the previous element on the stack.
     */
    function endElement($parser, $name) {
        // pop this element off the node stack
        $node = array_pop($this->node_stack);
        $node["_DATA"] = trim($node["_DATA"]);

        //$node[$node["_NAME"]]="moin";

        // and add it an an element of the last node in the stack...
        $lastnode = count($this->node_stack);

        //$count=count($this->node_stack[$lastnode+1]["_ELEMENTS"]);

        //$this->node_stack[$lastnode-1][$node["_NAME"]][0]=$node;

        array_push($this->node_stack[$lastnode-1]["_ELEMENTS"], $node);
    }

    //----------------------------------------------------------------------
    /** PROTECTED
     * Collect the data onto the end of the current chars.
     */
    function characterData($parser, $data) {
        // add this data to the last node in the stack...
        $lastnode = count($this->node_stack);
        $this->node_stack[$lastnode-1]["_DATA"] .= $data;

    }

    //----------------------------------------------------------------------
}

//######################################################################
//##  END OF CLASS
//######################################################################
?>