xml = $xml; // Set default values $this->version = '1.0'; $this->encoding = "ISO-8859-1"; $this->dtd = ''; $this->entities = array(); $this->xml_index = array(); $this->xml_reference = 0; $this->stack = array(); } function parse() { // Creates the object tree from XML code $this->parser = xml_parser_create($this->encoding); xml_set_object($this->parser, $this); xml_set_element_handler($this->parser, "startElement", "endElement"); xml_set_character_data_handler($this->parser, "characterData"); xml_set_default_handler($this->parser, "defaultHandler"); if (!xml_parse($this->parser, $this->xml)) { // Error while parsing document $err_code = xml_get_error_code(); $err_string = xml_get_error_string(); $err_line = xml_get_current_line_number(); $err_col = xml_get_current_column_number(); $err_byte = xml_get_current_byte_index(); print "

Error Code: $err_code
$err_string
Line: $err_line
Column: $err_col

"; } xml_parser_free($this->parser); } function generate() { // Generates XML string from the xml_doc::document object // Create document header if ($this->version == '' and $this->encoding == '') { $out_header = '<' . '?xml ?' . ">\n"; } elseif ($this->version != '' and $this->encoding == '') { $out_header = '<' . "?xml version=\"{$this->version}\"?" . ">\n"; } else { $out_header = '<' . "?xml version=\"{$this->version}\" encoding=\"{$this->encoding}\"?" . ">\n"; } if ($this->dtd != '') { $out_header .= "dtd . ">\n"; } // Get reference for root tag $_root =& $this->xml_index[0]; // Create XML for root tag $this->xml = $this->createXML(0); return $out_header . $this->xml; } function stack_location() { // Returns index for current working tag return $this->stack[(count($this->stack) - 1)]; } function startElement($parser, $name, $attrs=array()) { // Process a new tag // Check to see if tag is root-level if (count($this->stack) == 0) { // Tag is root-level (document) $this->document = new xml_tag($this,$name,$attrs); $this->document->refID = 0; $this->xml_index[0] =& $this->document; $this->xml_reference = 1; $this->stack[0] = 0; } else { // Get current location in stack array $parent_index = $this->stack_location(); // Get object reference to parent tag $parent =& $this->xml_index[$parent_index]; // Add child to parent $parent->addChild($this,$name,$attrs); // Update stack array_push($this->stack,($this->xml_reference - 1)); } } function endElement($parser, $name) { // Update stack array_pop($this->stack); } function characterData($parser, $data) { // Add textual data to the current tag // Get current location in stack array $cur_index = $this->stack_location(); // Get object reference for tag $tag =& $this->xml_index[$cur_index]; // Assign data to tag $tag->contents = $data; } function defaultHandler($parser, $data) { } function createTag($name, $attrs=array(), $contents='', $parentID = '') { // Creates an XML tag, returns Tag Index # if ($parentID === '') { // Tag is root-level $this->document = new xml_tag($this,$name,$attrs,$contents); $this->document->refID = 0; $this->xml_index[0] =& $this->document; $this->xml_reference = 1; return 0; } else { // Tag is a child // Get object reference to parent tag $parent =& $this->xml_index[$parentID]; // Add child to parent return $parent->addChild($this,$name,$attrs,$contents); } } function createXML($tagID,$parentXML='') { // Creates XML string for a tag object // Specify parent XML to insert new string into parent XML $final = ''; // Get Reference to tag object $tag =& $this->xml_index[$tagID]; $name = $tag->name; $contents = $tag->contents; $attr_count = count($tag->attributes); $child_count = count($tag->tags); $empty_tag = ($tag->contents == '') ? true : false; // Create intial tag if ($attr_count == 0) { // No attributes if ($empty_tag === true) { $final = "<$name />"; } else { $final = "<$name>$contents"; } } else { // Attributes present $attribs = ''; foreach ($tag->attributes as $key => $value) { $attribs .= ' ' . $key . "=\"$value\""; } if ($empty_tag === true) { $final = "<$name$attribs />\n"; } else { $final = "<$name$attribs>$contents\n"; } } // Search for children if ($child_count > 0) { foreach ($tag->tags as $childID) { $final = $this->createXML($childID,$final); } } if ($parentXML != '') { // Add tag XML to parent XML $stop1 = strrpos($parentXML,''); if ($stop1 > $stop2) { // Parent already has children $begin_chunk = substr($parentXML,0,$stop1); $end_chunk = substr($parentXML,$stop1,(strlen($parentXML) - $stop1 + 1)); $final = $begin_chunk . $final . $end_chunk; } elseif ($stop2 > $stop1) { // No previous children $spc = strpos($parentXML,' ',0); $parent_name = substr($parentXML,1,$spc - 1); if ($spc != $stop2) { // Attributes present $parent_attribs = substr($parentXML,$spc,($stop2 - $spc)); } else { // No attributes $parent_attribs = ''; } $final = "<$parent_name$parent_attribs>$final"; } } return $final; } function getTag($tagID,&$name,&$attributes,&$contents,&$tags) { // Returns tag information via variable references from a tag index# // Get object reference for tag $tag =& $this->xml_index[$tagID]; $name = $tag->name; $attributes = $tag->attributes; $contents = $tag->contents; $tags = $tag->tags; } function &getTagByID($tagID) { // Returns tag information via variable references from a tag index# // Get object reference for tag $tag =& $this->xml_index[$tagID]; return $tag; } function getChildByName($parentID,$childName,$startIndex=0) { // Returns child index# searching by name // Get reference for parent $parent =& $this->xml_index[$parentID]; if ($startIndex > count($parent->tags)) return false; for ($i = $startIndex; $i < count($parent->tags); $i++) { $childID = $parent->tags[$i]; // Get reference for child $child =& $this->xml_index[$childID]; if ($child->name == $childName) { // Found child, return index# return $childID; } } } } class xml_tag { var $refID; // Unique ID number of the tag var $name; // Name of the tag var $attributes = array(); // Array (assoc) of attributes for this tag var $tags = array(); // An array of refID's for children tags var $contents; // textual (CDATA) contents of a tag var $children = array(); // Collection (type: xml_tag) of child tag's function xml_tag(&$document,$tag_name,$tag_attrs=array(),$tag_contents='') { // Constructor function for xml_tag class // Set object variables $this->name = $tag_name; $this->attributes = $tag_attrs; $this->contents = $tag_contents; $this->tags = array(); // Initialize children array/collection $this->children = array(); } function addChild (&$document,$tag_name,$tag_attrs=array(),$tag_contents='') { // Adds a child tag object to the current tag object // Create child instance $this->children[(count($this->children))] = new xml_tag($document,$tag_name,$tag_attrs,$tag_contents); // Add object reference to document index $document->xml_index[$document->xml_reference] =& $this->children[(count($this->children) - 1)]; // Assign document index# to child $document->xml_index[$document->xml_reference]->refID = $document->xml_reference; // Add child index# to parent collection of child indices array_push($this->tags,$document->xml_reference); // Update document index counter $document->xml_reference++; // Return child index# return ($document->xml_reference - 1); } } ?>