From: <jhe...@us...> - 2002-07-29 11:05:02
|
Update of /cvsroot/upcase-project/UpCase/lib In directory usw-pr-cvs1:/tmp/cvs-serv16711 Added Files: uc_xmlparser.php Log Message: Simple generic xml parser that output a "tree" from a xml file. --- NEW FILE: uc_xmlparser.php --- <?php class Node { /** * Child nodes * * @var array */ var $childNodes; /** * Count of child nodes * * @var int */ var $childCount; /** * Text child elements * * @var array */ var $textElements; /** * XML attributes * * @var array */ var $attributes; /** * Tag name * * @var string */ var $tag; /** * Create a new node object * * @param string $tag tagname of the node * @param array $attributes xml attributes to assign to this node */ function Node($tag, $attributes = 0) { $this->tag = $tag; if ($attributes) $this->attributes = $attributes; $this->childNodes = array(); $this->childCount = 0; $this->textElements = array(); } /** * Add a node to the list of child nodes and increment the child nodei * counter. * * @param object $node The child node object */ function appendChild($node) { $this->childNodes[$this->childCount] = $node; $this->childCount ++; } /** * Add a string of data text to text elements list * * @param string $data text data */ function appendData($data) { $this->textElements[] = $data; } /** * Get the last child node * * @return object reference to the last child node */ function &lastChild() { return $this->childNodes[$this->childCount - 1]; } /** * retrieve an array of child nodes by tagname * * @param string $tag the tagname of child elements * @return array List of all nodes below this one with tagname */ function getElements($tag) { $ret = array(); foreach ($this->childNodes as $child) { if ($child->tag == $tag) $ret[] = $child; if ($child->childCount > 0) $ret = array_merge($ret, $child->getElements($tag)); } return $ret; } } /** * Very basic and limited XML parser. * * This parser will read a XML file and return a structure like this * * object Node ( * [childNodes] => array ( * [0] => object Node ( ... * [1] => object Node ( ... * ) * [childCount] => 2 * [textElements] => array ( * [0] => "blah blah ..." * [1] => "blah blah blah ..." * ) * [attributes] => array ( [attrib1] => "blah" * [attrib2] => "blahblah" * ) * [tag] => "root" * ) * * Then : * * $node->childNodes is the list of all direct childs of this node * $node->childCount is the number of direct childs under this node * $node->tag is the tag name of this node * $node->attributes is the list of xml attributes of this node * $node->textElements is the list of all textual data in this node * */ class UcXmlParser { var $parser; var $inComment; var $domTree; var $stack; var $stackTop; function UcXmlParser() { $this->parser = xml_parser_create(); xml_set_object($this->parser, &$this); xml_parser_set_option($this->parser, XML_OPTION_SKIP_WHITE, 1); xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); xml_set_default_handler($this->parser, "defaultHandler"); xml_set_element_handler($this->parser, "openTag", "closeTag"); } function parse($xmlFile) { $this->inComment = false; $data = implode("", file($xmlFile)); $this->domTree = new Node("root"); $this->stack = array(); $this->stackTop = 0; $this->stack[$this->stackTop] =& $this->domTree; xml_parse($this->parser, $data, true); return $this->domTree; } function openTag($parser, $tag, $attributes) { // Open a tag, create a new node $node = new Node($tag, $attributes); // and append it to the current one $this->stack[$this->stackTop]->appendChild($node); // Then put it on top of the stack $this->stack[$this->stackTop + 1] =& $this->stack[$this->stackTop]->lastChild(); $this->stackTop ++; } function closeTag($parser, $tag) { // Closing a node, ddecrease stack top, so current node is the // parent of the one we just closed $this->stackTop--; } function defaultHandler($parser, $xmlData) { $data = trim($xmlData); // Don't need this if ($data == "<?xml version=\"1.0\"?>" || $data == "") return; // Nor that ... if (strpos($data, "<!--") !== false && !$this->inComment) { if (strpos($data, "-->") !== false) return; $this->inComment = true; return; } if (strpos($data, "-->") !== false && $this->inComment) { $this->inComment = false; return; } // This is a text element, then append it to the data of the // current node if (!$this->inComment) $this->stack[$this->stackTop]->appendData($data); } } ?> |