1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
| <?php
/**
* XML parser
*
* @author McArrow
*/
class ivXmlParser
{
/**
* XML parser resource
* @var resource
*/
var $_parser = null;
/**
* Node stack
* @var ivStack
*/
var $_nodeStack = null;
/**
* Head node
* @var ivXml
*/
var $_head = null;
/**
* Constructor
*
*/
function ivXmlParser()
{
$this->__construct();
}
/**
* Constructor
*
*/
function __construct()
{
$this->_parser = xml_parser_create('UTF-8');
xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, 0);
xml_parser_set_option($this->_parser, XML_OPTION_SKIP_WHITE, 1);
xml_parser_set_option($this->_parser, XML_OPTION_TARGET_ENCODING, 'UTF-8');
xml_set_object($this->_parser, $this);
xml_set_element_handler($this->_parser, '_startElementHandle', '_endElementHandle');
xml_set_character_data_handler($this->_parser, '_elementDataHandle');
}
/**
* Parse XML string
*
* @param string $xmlString
* @return ivXml
*/
function &parse($xmlString)
{
$this->_nodeStack = new ivStack();
if (!xml_parse($this->_parser, $xmlString)) {
return false;
}
$result = &$this->_head;
return $result;
}
function getLastError()
{
return array(
'errorCode' => xml_get_error_code($this->_parser),
'errorString' => xml_error_string(xml_get_error_code($this->_parser)),
'line' => xml_get_current_line_number($this->_parser),
'char' => xml_get_current_column_number($this->_parser) + 1
);
}
/**
* Handle start element
*
* @param resource $parser
* @param string $name Node name
* @param array $attrs Node attributes
*/
function _startElementHandle($parser, $name, $attrs)
{
$currentNode = &ivXmlNode::create($name, $attrs);
// Need to use container for node because of bug in xmlparser with multibyte encodings
$container = new stdClass();
$container->node = &$currentNode;
$container->value = null;
$last = &$this->_nodeStack->tail();
if ($last) {
$last->node->addChild($currentNode);
} else {
$this->_head = &$currentNode;
}
$this->_nodeStack->push($container);
}
/**
* Handle end element
*
* @param resource $parser
* @param string $name Node name
*/
function _endElementHandle($parser, $name)
{
$last = &$this->_nodeStack->tail();
$last->node->setValue($last->value);
$this->_nodeStack->pop();
}
/**
* Handle element's value
*
* @param resource $parser
* @param string $data Node value
*/
function _elementDataHandle($parser, $data)
{
$last = &$this->_nodeStack->tail();
$last->value .= (string) $data;
}
}
?> |
Partager