9 * @author Greg Beaver <cellog@php.net>
10 * @author Stephan Schmidt (original XML_Unserializer code)
11 * @copyright 1997-2009 The Authors
12 * @license http://opensource.org/licenses/bsd-license New BSD License
13 * @version CVS: $Id: XMLParser.php 313023 2011-07-06 19:17:11Z dufuz $
14 * @link http://pear.php.net/package/PEAR
15 * @since File available since Release 1.4.0a1
19 * Parser for any xml file
22 * @author Greg Beaver <cellog@php.net>
23 * @author Stephan Schmidt (original XML_Unserializer code)
24 * @copyright 1997-2009 The Authors
25 * @license http://opensource.org/licenses/bsd-license New BSD License
26 * @version Release: 1.9.4
27 * @link http://pear.php.net/package/PEAR
28 * @since Class available since Release 1.4.0a1
34 * @var string $_serializedData
36 var $_unserializedData = null;
39 * name of the root tag
45 * stack for all data that is found
46 * @var array $_dataStack
48 var $_dataStack = array();
51 * stack for all values that are generated
52 * @var array $_valStack
54 var $_valStack = array();
63 * The XML encoding to use
64 * @var string $encoding
66 var $encoding = 'ISO-8859-1';
73 return $this->_unserializedData;
77 * @param string xml content
78 * @return true|PEAR_Error
82 if (!extension_loaded('xml')) {
83 include_once 'PEAR.php';
84 return PEAR::raiseError("XML Extension not found", 1);
86 $this->_dataStack = $this->_valStack = array();
90 strpos($data, 'encoding="UTF-8"')
91 || strpos($data, 'encoding="utf-8"')
92 || strpos($data, "encoding='UTF-8'")
93 || strpos($data, "encoding='utf-8'")
95 $this->encoding = 'UTF-8';
98 if (version_compare(phpversion(), '5.0.0', 'lt') && $this->encoding == 'UTF-8') {
99 $data = utf8_decode($data);
100 $this->encoding = 'ISO-8859-1';
103 $xp = xml_parser_create($this->encoding);
104 xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, 0);
105 xml_set_object($xp, $this);
106 xml_set_element_handler($xp, 'startHandler', 'endHandler');
107 xml_set_character_data_handler($xp, 'cdataHandler');
108 if (!xml_parse($xp, $data)) {
109 $msg = xml_error_string(xml_get_error_code($xp));
110 $line = xml_get_current_line_number($xp);
111 xml_parser_free($xp);
112 include_once 'PEAR.php';
113 return PEAR::raiseError("XML Error: '$msg' on line '$line'", 2);
115 xml_parser_free($xp);
120 * Start element handler for XML parser
123 * @param object $parser XML parser object
124 * @param string $element XML element
125 * @param array $attribs attributes of XML tag
128 function startHandler($parser, $element, $attribs)
131 $this->_dataStack[$this->_depth] = null;
137 'childrenKeys' => array(),
138 'aggregKeys' => array()
141 if (count($attribs) > 0) {
142 $val['children'] = array();
143 $val['type'] = 'array';
144 $val['children']['attribs'] = $attribs;
147 array_push($this->_valStack, $val);
153 * @param string $data
154 * @param string $element element name
156 function postProcess($data, $element)
162 * End element handler for XML parser
165 * @param object XML parser object
169 function endHandler($parser, $element)
171 $value = array_pop($this->_valStack);
172 $data = $this->postProcess($this->_dataStack[$this->_depth], $element);
174 // adjust type of the value
175 switch (strtolower($value['type'])) {
176 // unserialize an array
179 $value['children']['_content'] = $data;
182 $value['value'] = isset($value['children']) ? $value['children'] : array();
186 * unserialize a null value
193 * unserialize any scalar value
196 settype($data, $value['type']);
197 $value['value'] = $data;
201 $parent = array_pop($this->_valStack);
202 if ($parent === null) {
203 $this->_unserializedData = &$value['value'];
204 $this->_root = &$value['name'];
208 // parent has to be an array
209 if (!isset($parent['children']) || !is_array($parent['children'])) {
210 $parent['children'] = array();
211 if ($parent['type'] != 'array') {
212 $parent['type'] = 'array';
216 if (!empty($value['name'])) {
217 // there already has been a tag with this name
218 if (in_array($value['name'], $parent['childrenKeys'])) {
219 // no aggregate has been created for this tag
220 if (!in_array($value['name'], $parent['aggregKeys'])) {
221 if (isset($parent['children'][$value['name']])) {
222 $parent['children'][$value['name']] = array($parent['children'][$value['name']]);
224 $parent['children'][$value['name']] = array();
226 array_push($parent['aggregKeys'], $value['name']);
228 array_push($parent['children'][$value['name']], $value['value']);
230 $parent['children'][$value['name']] = &$value['value'];
231 array_push($parent['childrenKeys'], $value['name']);
234 array_push($parent['children'],$value['value']);
236 array_push($this->_valStack, $parent);
242 * Handler for character data
245 * @param object XML parser object
246 * @param string CDATA
249 function cdataHandler($parser, $cdata)
251 $this->_dataStack[$this->_depth] .= $cdata;