PHP Classes

File: XMLTools.php

Recommend this page to a friend!
  Classes of Andrey Nikishaev   XML Tools   XMLTools.php   Download  
File: XMLTools.php
Role: Class source
Content type: text/plain
Description: Main class
Class: XML Tools
Parse and validate XML documents
Author: By
Last change:
Date: 12 years ago
Size: 6,687 bytes
 

Contents

Class file image Download
<?php
/**
    XML parser & validator
 
    @author Andrey Nikishaev
   
    If parent node tag name equal children tag name but ends with 's' then
    it will be an array.
    For example:
        <tournaments>
            <tournament></tournament>
        </tournaments>
       
    Else it will be an associative array and duplicated tags will be deleted.
   
    If node has no elements and ends with "s" like "<pages></pages>" then it will
    be empty array.
   
    Example of use:

    $xmltools = new XMLTools();

    $isvalid = $xmltools->ValidateXML('test.xml','test.xsd');
    if($isvalid)
        // return True
        $data = $xmltools->XML2Array('test.xml')
    else
        // returned array of errors
        print_r($isvalid);
   
    XML like:
   
    <tournaments>
        <tournament>
            <options>
                <resultType>maxWeight|maxSumWeight|totalCount</resultType>
                <startType>weekly|monthly</startType>
                <startDay>2</startDay>
                <fishtypes>
                    <fishtype>1</fishtype>
                    <fishtype>2</fishtype>
                </fishtypes>
                <pages>
                </pages>
                <map_pid>1</map_pid>
                <location_pid>1</location_pid>
            </options>
            <variants>
                <variant timeStart="01:50" timeEnd="02:50" name="Canadian losos" />
                <variant timeStart="02:50" timeEnd="03:50" name="Canadian losos" />
                <variant timeStart="03:50" timeEnd="04:50" name="Canadian losos" />
            </variants>
        </tournament>
    </tournaments>
   
    Will be parsed as:
   
    Array
    (
        [0] => Array
            (
                [options] => Array
                    (
                        [resultType] => maxWeight|maxSumWeight|totalCount
                        [startType] => weekly|monthly
                        [startDay] => 2
                        [fishtypes] => Array
                            (
                                [0] => 1
                                [1] => 2
                            )

                        [pages] => Array()
                        [map_pid] => 1
                        [location_pid] => 1
                    )

                [variants] => Array
                    (
                        [0] => Array
                            (
                                [timeStart] => 01:52
                                [timeEnd] => 02:50
                                [name] => Canadian losos
                            )

                    )

            )

    )
 
 */
class XMLTools {

    public function
XML2Array($file) {
        if (!(
$fp = fopen($file, "r"))) {
            die(
"could not open XML input");
        }

       
$contents = fread($fp, filesize($file));
       
fclose($fp);

        if(!
$contents) return array();

        if(!
function_exists('xml_parser_create')) {
            throw new
Exception("'xml_parser_create()' function not found!");
            return
null;
        }

       
//Get the XML parser of PHP - PHP must have this module for the parser to work
       
$parser = xml_parser_create('');
       
xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8");
       
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
       
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
       
xml_parse_into_struct($parser, trim($contents), $xml_values);
       
xml_parser_free($parser);

        if(!
$xml_values) return;//Hmm...

        //Initializations
       
$xml_array = array();
       
$parents = array();
       
$level = 0;
       
$is_array = array();
       
       
$current = &$xml_array; //Refference

       
$dc = count($xml_values);
        for(
$i=0;$i<$dc;$i++) {
       
           
$data = $xml_values[$i];
            if(!isset(
$is_array[$data['level']]) && ($data['level'] > 1) && ($data['tag'].'s' == $xml_values[$i-1]['tag'] || $data['tag'].'es' == $xml_values[$i-1]['tag'])) {
               
$is_array[$data['level']] = true;
            }
           
$level = $data['level'];
           
            if(
$data['type'] == 'open') {
               
               
$c = array();
                if(isset(
$data['attributes'])) $c = $data['attributes'];
                if(!isset(
$is_array[$level])) {
                   
$current[$data['tag']] = $c;
                   
$parents[$level] = &$current;
                   
$current = &$current[$data['tag']];
                   
                } else {
                   
$current[] = $c;
                   
$parents[$level] = &$current;
                   
$current = &$current[count($current)-1];
                }
               
               
            } else if(
$data['type'] == 'complete') {
               
$c = (substr($data['tag'], -1)=="s")?array():null;
                if(isset(
$data['attributes'])) $c = $data['attributes'];
                if(isset(
$data['value']) && isset($data['attributes'])) $c = array_merge($c,array('value'=>trim($data['value'])));
                if(isset(
$data['value']) && !isset($data['attributes'])) $c = trim($data['value']);

                if(isset(
$is_array[$level])) {
                   
$current[] = $c;
                } else {
                   
$current[$data['tag']] = $c;
                }
               
            } else {
                unset(
$is_array[$level+1]);
               
$current = &$parents[$level];
               
            }
           
        }
        
        return
$xml_array;
    }

    private function
_libxml_display_error($error) {
       
$return = "Error in $error->file (Line:{$error->line}):";
       
$return .= trim($error->message);
        return
$return;
    }

    private function
_libxml_display_errors() {

       
$errors = libxml_get_errors();
       
$res = array();
        foreach (
$errors as $error) {
           
$res[] = $this->_libxml_display_error($error);
        }
       
libxml_clear_errors();
        return
$res;
    }

    public function
ValidateXML($xml,$schema) {
        if(!
class_exists('DOMDocument')) {
            throw new
Exception("'DOMDocument' class not found!");
            return
False;
        }

       
libxml_use_internal_errors(true);

        if (!(
$fp = fopen($xml, "r"))) {
            die(
"could not open XML input");
        }

       
$contents = fread($fp, filesize($xml));
       
fclose($fp);

       
$xml = new DOMDocument();
       
$xml->loadXML($contents);

        if (!
$xml->schemaValidate($schema)) {
            return
$this->_libxml_display_errors();
        } else {
            return
True;
        }
    }
}