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);
}
}
?>
|