Premium Programming Simple XML Parser

The following parser will work for simple XML files with no attributes.

Here is the HTML code to put on your website

include 'premium_programming_xml.class.php';

$p = new PremiumXML();
$xml = $p->xml_load_filename('sample.xml');

print_r($xml);

Here is sample.xml

<SampleXML>
	<Customer>
		<Name>Aaron</Name>
		<Position>Computer Programmer</Position>
	</Customer>
	<Customer>
		<Name>Phil Dunphy</Name>
		<Position>Real Estate Agent</Position>
		<MarriedTo>
			<Name>Claire Dunphy</Name>
		</MarriedTo>
	</Customer>
	<BusinessName>Your Company Name Here</BusinessName>
</SampleXML>

Here is the output

SimpleXMLObject Object
(
    [Customer] => Array
        (
            [0] => SimpleXMLObject Object
                (
                    [Name] => Aaron
                    [Position] => Computer Programmer
                )

            [1] => SimpleXMLObject Object
                (
                    [Name] => Phil Dunphy
                    [Position] => Real Estate Agent
                    [MarriedTo] => SimpleXMLObject Object
                        (
                            [Name] => Claire Dunphy
                        )

                )

        )

    [BusinessName] => Your Company Name Here
)

Here is the premium_programming_xml.class.php file.

<?php

/* This code was written by Aaron Jay Lieberman on 11/13/10 
This class creates a SimpleXML object for an XML string.  It assumes simple 
XML formatting and was written to overcome large XML string sizes.
It is a replacement for simplexml_load_string for PHP4 and 
doesn't use any PHP XML classes
*/

class SimpleXMLObject {
	function attributes(){
		$container = get_object_vars($this);
		return (object) $container["@attributes"];
	}
	function content(){
		$container = get_object_vars($this);
		return (object) $container["@content"];
	}

}


class PremiumXML {
	function GetNextTag(&$st, &$tag, &$value) {	
		// get tag name
		$st = trim($st);
		$i = strpos($st, '<');
		if ($i === false || $i != 0) {
			echo "invalid XML. i = $i " . htmlspecialchars($st);
			exit;
		}
		$j = strpos($st, '>');
		if ($j === false) {
			echo "invalid xml j";
			exit;
		}
		$tag = substr($st, 1, $j-1);
		
		$k = strpos($st, '</' . $tag . '>');
		if ($k === false) {
			echo " invalid xml k tag = &quot;$tag&quot;<br><br>\n";
			exit;
		}
		
		// if this is a big string.. try to get the whole array
		$returnarray = 0;
		if (1000 < strlen($st)) {
			$i = strpos($st, '</' . $tag . '>' . '<' . $tag . '>');
			if ($i !== false) { // lets try to get the array
				$value = explode('</' . $tag . '>' . '<' . $tag . '>', $st);
				$st = $value[sizeof($value)-1];

				$k = strpos($st, '</' . $tag . '>');
				if ($k === false) {
					echo " invalid xml k2";
					exit;
				}
				$value[0] = substr($value[0], strlen($tag) + 2);
				
				$value[sizeof($value)-1] = (String) substr($st, 0, $k);
				$st = substr($st, $k + strlen($tag) + 3);
				$returnarray = 1;
			}
		}
		if (! $returnarray) {
			$value = (String) substr($st, strlen($tag) + 2, $k - $j - 1);
			$st = substr($st, $k + strlen($tag) + 3);
		}
	}

	function xml_load_string($st, $level = 0) {
		if ($level == 100) {
			echo " too deep ";
			exit;
		}
		if ($level == 0) {
			$st = trim($st);
			$st = preg_replace('/>\s</', '><', $st);
			// check if the header is there.
			if (preg_match('<' . '\?xml .*\?' . '>', $st)) {
				$st = trim(preg_replace('/<' . '\?xml .*\?' . '>/', '', $st));
			}
		}
		
		if ($st == '') {
			return 0;
		}
		
		if (strpos($st, '<') === false) { // this is the inside value... nothing left
			return $st;
		}
		
		$ans = new SimpleXMLObject;
		while ($st != '') {
			$this->GetNextTag($st, $key, $value);
			if (is_array($value)) {
				foreach ($value as $item) {
					$item = $this->xml_load_string($item, $level + 1);
					if (array_key_exists($key, $ans)) {
						if (sizeof($ans->$key) == 1) {
							$ans->$key = array($ans->$key, $item);
						} else {
							$ArrayKey = sizeof($ans->$key);
							$ans->{$key}[] = $item;
						}
					} else {
						$ans->$key = $item;
					}
				}
			} else {
				if ($value != '') { 
					$value = $this->xml_load_string($value, $level + 1);
				}
				if (array_key_exists($key, $ans)) {
					if (sizeof($ans->$key) == 1) {
						$ans->$key = array($ans->$key, $value);
					} else {
						$ArrayKey = sizeof($ans->$key);
						$ans->{$key}[] = $value;
					}
				} else {
					$ans->$key = $value;
				}
			}
		}
		
		if ($level == 0) { // just return the inside
			return $value;
		} else {
			return $ans;
		}
	}
	
	function xml_load_filename($filename) {
		if (! file_exists($filename)) {
			die('filename: ' . $filename . '  does not exist in xml_load_filename');
		}
		$XMLString = file_get_contents($filename);
		$p = new PremiumXML;     
		$xml = $p->xml_load_string($XMLString);
	   return $xml;
	}
}

?>