Virtlab:Řídící server/XmlParser.php.inc

Z VirtlabWiki

< Virtlab:Řídící serverVerze z 00:01, 10. 1. 2007; zobrazit aktuální verzi
← Starší verze | Novější verze →
Přejít na: navigace, hledání

Obsah

Popis základní myšlenky

Tato třída zajišťuje převod XML souborů na asociativní pole metodou SAX.

Tvorba pole probíha na principu "zásobníku". Postupně se při otevíracích značkách tvoří pole, která mají jen položku attribs vyplněnou polem atributu. Pokud se zpracovávají data značky, tak se vloží do položky pole content posledniho prvku (pole) "zásobniku". Funkce pro obsluhu uzavírací značky vyzvedne poslední položku "zásobníku" a vloží ji do předchozí položky zásobníku pod položku child. Tímto postupem se postupně tvoří strom polí, které obsahujé data z XML (pro výpis celé struktury lze použít funkci print_r).

Ukázka

Vzorová XML data

<?xml version="1.0" encoding="utf-8" ?>
<equipment>
   <device type="router" name="r1" serial_number="12345-54321" platform="7200">
      <os>
         <major>12</major>
         <minor>8</minor>
      </os>
      <interfaces>
         <interface technology="serial" connect_group="1" name="s0/1/1">
            <max_bps>128000</max_bps>
            <int_feature>+++</int_feature>
         </interface>
         <interface technology="ethernet" ether_type="legacy" connect_group="2" name="e0">
            <int_feature>802.1q</int_feature>
         </interface>
      </interfaces>
      <special>
         <feature>mpls</feature>
         <feature>+++</feature>
         <feature>***</feature>
      </special>
   </device>

   <device type="router" name="r3" serial_number="2345-5432">
      <os>
         <major>12</major>
         <minor>6</minor>
         <other>321-ipsec:XXX</other>
      </os>
      <interfaces>
         <interface technology="serial" connect_group="1" name="s0">
            <max_bps>64000</max_bps>
         </interface>
         <interface technology="ethernet" ether_type="fast" connect_group="3" name="fa0/0">
         </interface>
         <interface technology="ethernet" ether_type="fast" connect_group="3" name="fa0/1">
         </interface>
      </interfaces>
   </device>
</equipment>

Výstup parseru (vytištěno pomocí funkce print_r)

Array
(
  [0] => Array
   (
      [name] => EQUIPMENT
         [content] =>      
         [child] => Array
            (
               [0] => Array
                  (
                     [name] => DEVICE
                     [attribs] => Array
                        (
                           [TYPE] => router
                           [NAME] => r1
                           [SERIAL_NUMBER] => 12345-54321
                           [PLATFORM] => 7200
                        )
                     [content] =>                 
                     [child] => Array
                        (
                           [0] => Array
                              (
                                 [name] => OS
                                 [content] =>                   
                                 [child] => Array
                                    (
                                       [0] => Array
                                          (
                                             [name] => MAJOR
                                             [content] => 12
                                          )
                                       [1] => Array
                                          (
                                             [name] => MINOR
                                             [content] => 8
                                          )
                                    )
                              )
                           [1] => Array
                              (
                                 [name] => INTERFACES
                                 [content] =>                   
                                 [child] => Array
                                    (
                                       [0] => Array
                                          (
                                             [name] => INTERFACE
                                             [attribs] => Array
                                                (
                                                   [TECHNOLOGY] => serial
                                                   [CONNECT_GROUP] => 1
                                                   [NAME] => s0/1/1
                                                )
                                             [content] =>                          
                                             [child] => Array
                                                (
                                                   [0] => Array
                                                      (
                                                         [name] => MAX_BPS
                                                         [content] => 128000
                                                      )
                                                   [1] => Array
                                                      (
                                                         [name] => INT_FEATURE
                                                         [content] => +++
                                                      )
                                                )
                                          )
                                       [1] => Array
                                          (
                                             [name] => INTERFACE
                                             [attribs] => Array
                                                (
                                                   [TECHNOLOGY] => ethernet
                                                   [ETHER_TYPE] => legacy
                                                   [CONNECT_GROUP] => 2
                                                   [NAME] => e0
                                                )
                                             [content] =>                 
                                             [child] => Array
                                                (
                                                   [0] => Array
                                                      (
                                                         [name] => INT_FEATURE
                                                         [content] => 802.1q
                                                      )
                                                )
                                          )
                                    )
                              )
                           [2] => Array
                              (
                                 [name] => SPECIAL
                                 [content] =>                   
                                 [child] => Array
                                    (
                                       [0] => Array
                                          (
                                             [name] => FEATURE
                                             [content] => mpls
                                          )
                                       [1] => Array
                                          (
                                             [name] => FEATURE
                                             [content] => ***
                                          )
                                    )
                              )
                        )
                  )
               [1] => Array
                  (
                     [name] => DEVICE
                     [attribs] => Array
                        (
                           [TYPE] => router
                           [NAME] => r3
                           [SERIAL_NUMBER] => 2345-5432
                        )
                     [content] =>            
                     [child] => Array
                        (
                           [0] => Array
                              (
                                 [name] => OS
                                 [content] =>                   
                                 [child] => Array
                                    (
                                       [0] => Array
                                          (
                                             [name] => MAJOR
                                             [content] => 12
                                          )
                                       [1] => Array
                                          (
                                             [name] => MINOR
                                             [content] => 6
                                          )
                                    )
                              )
                           [1] => Array
                              (
                                 [name] => INTERFACES
                                 [content] =>            
                                 [child] => Array
                                    (
                                       [0] => Array
                                          (
                                             [name] => INTERFACE
                                             [attribs] => Array
                                                (
                                                   [TECHNOLOGY] => ethernet
                                                   [ETHER_TYPE] => fast
                                                   [CONNECT_GROUP] => 3
                                                   [NAME] => fa0/1
                                                )
                                             [content] =>        
                                          )
                                    )
                              )
                        )
                  )
            )
      )
)
<?
class xmlParser{
    var $xml_obj = null;
    var $output = array();
    var $attrs;

/*    konstruktor - vytvari XML parser a registuje funkce obsluhujici
 *     zpetne volani (oteviraci tag, data, uzaviraci tag)
 */
    function xmlParser() {
        $this->xml_obj = xml_parser_create();
        xml_set_object($this->xml_obj,$this);
        xml_set_character_data_handler($this->xml_obj, "dataHandler");
        xml_set_element_handler($this->xml_obj, "startHandler", "endHandler");
   }//function


/*    funkce nacita ze vstupniho souboru data a predava je parseru
 */
    function parse($path) {
        if(!($fp = fopen($path, "r"))) {
            die("Cannot open XML data file: $path");
            return false;
        }
        while ($data = fread($fp, 4096)) {
            if(!xml_parse($this->xml_obj, $data, feof($fp))) {
                die(sprintf("XML error: %s at line %d",
                    xml_error_string(xml_get_error_code($this->xml_obj)),
                    xml_get_current_line_number($this->xml_obj)));
            }
        }
        xml_parser_free($this->xml_obj);
        return true;
    }//function


    function parse_data($data) {
        $new = utf8_encode($data);    
        if(!xml_parse($this->xml_obj, $data, 1)) {
                die(sprintf("XML error: %s at line %d",
                    xml_error_string(xml_get_error_code($this->xml_obj)),
                    xml_get_current_line_number($this->xml_obj)));
            }
        xml_parser_free($this->xml_obj);
        return true;
    }//function


/* funkce pro obluhu oteviraciho tagu
 *     vytvari asociativni pole s polozkami "name" (obsahujici
 *     jmeno tagu) a polozku "attribs", ktera se naplni atributy
 *     tagu (asociativni pole - indexy jsou nazvy atributu)
 */
    function startHandler($parser, $name, $attribs) {
        $_content = array();
        $_content['name'] = $name;
        if(!empty($attribs))
            $_content['attribs'] = $attribs;
        array_push($this->output, $_content);
    }//function


/* funkce pro obsluhu dat tagu
 *     vytvori asociativni polozku pole s nazvem "content"
 */
    function dataHandler($parser, $data) {
        if(!empty($data) && $data!="\n") {
            $_output_idx = count($this->output) - 1;
            $this->output[$_output_idx]['content'] .= $data;
        }
    }//function


/* funkce pro obsluhu uzaviraciho tagu
 *     vezme posledni polozku "zasobniku" a umisti ji do predchoziho
 *     prvku "zasobniku" do acociativni polozky "child"
 */
    function endHandler($parser, $name) {
        if(count($this->output) > 1) {
            $_data = array_pop($this->output);
            $_output_idx = count($this->output) - 1;
            $add = array();
            if(!$this->output[$_output_idx]['child'])
                $this->output[$_output_idx]['child'] = array();
            array_push($this->output[$_output_idx]['child'], $_data);
        }   
    }//function
}//class
?>
Osobní nástroje