4 public function __construct() {
17 public function getNodeName() {
18 if($this->nodeType != Xml::$Element) {
19 throw new HException("bad nodeType");
21 return $this->_nodeName;
23 public function setNodeName($n) {
24 if($this->nodeType != Xml::$Element) {
25 throw new HException("bad nodeType");
27 return $this->_nodeName = $n;
29 public function getNodeValue() {
30 if($this->nodeType == Xml::$Element || $this->nodeType == Xml::$Document) {
31 throw new HException("bad nodeType");
33 return $this->_nodeValue;
35 public function setNodeValue($v) {
36 if($this->nodeType == Xml::$Element || $this->nodeType == Xml::$Document) {
37 throw new HException("bad nodeType");
39 return $this->_nodeValue = $v;
41 public function getParent() {
42 return $this->_parent;
44 public function get($att) {
45 if($this->nodeType != Xml::$Element) {
46 throw new HException("bad nodeType");
48 return $this->_attributes->get($att);
50 public function set($att, $value) {
51 if($this->nodeType != Xml::$Element) {
52 throw new HException("bad nodeType");
54 $this->_attributes->set($att, htmlspecialchars($value, ENT_COMPAT, "UTF-8"));
56 public function remove($att) {
57 if($this->nodeType != Xml::$Element) {
58 throw new HException("bad nodeType");
60 $this->_attributes->remove($att);
62 public function exists($att) {
63 if($this->nodeType != Xml::$Element) {
64 throw new HException("bad nodeType");
66 return $this->_attributes->exists($att);
68 public function attributes() {
69 if($this->nodeType != Xml::$Element) {
70 throw new HException("bad nodeType");
72 return $this->_attributes->keys();
74 public function iterator() {
75 if($this->_children === null) {
76 throw new HException("bad nodetype");
80 $it = _hx_anonymous(array("cur" => 0, "x" => $me->_children, "hasNext" => array(new _hx_lambda(array("it" => &$it, "me" => &$me), null, array(), "{
81 return \$it->cur < _hx_len(\$it->x);
82 }"), 'execute0'), "next" => array(new _hx_lambda(array("it" => &$it, "me" => &$me), null, array(), "{
83 return \$it->x[\$it->cur++];
87 public function elements() {
88 if($this->_children === null) {
89 throw new HException("bad nodetype");
93 $it = _hx_anonymous(array("cur" => 0, "x" => $me->_children, "hasNext" => array(new _hx_lambda(array("it" => &$it, "me" => &$me), null, array(), "{
95 \$l = _hx_len(\$it->x);
97 if(_hx_array_get(\$it->x, \$k)->nodeType == Xml::\$Element) {
105 }"), 'execute0'), "next" => array(new _hx_lambda(array("it" => &$it, "me" => &$me), null, array(), "{
107 \$l = _hx_len(\$it->x);
111 if(\$n->nodeType == Xml::\$Element) {
121 public function elementsNamed($name) {
122 if($this->_children === null) {
123 throw new HException("bad nodetype");
127 $it = _hx_anonymous(array("cur" => 0, "x" => $me->_children, "hasNext" => array(new _hx_lambda(array("it" => &$it, "me" => &$me, "name" => &$name), null, array(), "{
129 \$l = _hx_len(\$it->x);
132 if(\$n->nodeType == Xml::\$Element && \$n->_nodeName == \$name) {
140 }"), 'execute0'), "next" => array(new _hx_lambda(array("it" => &$it, "me" => &$me, "name" => &$name), null, array(), "{
142 \$l = _hx_len(\$it->x);
146 if(\$n->nodeType == Xml::\$Element && \$n->_nodeName == \$name) {
156 public function firstChild() {
157 if($this->_children === null) {
158 throw new HException("bad nodetype");
160 if($this->_children->length === 0) {
163 return $this->_children[0];
165 public function firstElement() {
166 if($this->_children === null) {
167 throw new HException("bad nodetype");
170 $l = $this->_children->length;
172 $n = $this->_children[$cur];
173 if($n->nodeType == Xml::$Element) {
181 public function addChild($x) {
182 if($this->_children === null) {
183 throw new HException("bad nodetype");
185 if($x->_parent !== null) {
186 $x->_parent->_children->remove($x);
189 $this->_children->push($x);
191 public function removeChild($x) {
192 if($this->_children === null) {
193 throw new HException("bad nodetype");
195 $b = $this->_children->remove($x);
201 public function insertChild($x, $pos) {
202 if($this->_children === null) {
203 throw new HException("bad nodetype");
205 if($x->_parent !== null) {
206 $x->_parent->_children->remove($x);
209 $this->_children->insert($pos, $x);
211 public function toString() {
212 if($this->nodeType == Xml::$PCData) {
213 return $this->_nodeValue;
215 if($this->nodeType == Xml::$CData) {
216 return ("<![CDATA[" . $this->_nodeValue) . "]]>";
218 if($this->nodeType == Xml::$Comment || $this->nodeType == Xml::$DocType || $this->nodeType == Xml::$Prolog) {
219 return $this->_nodeValue;
222 if($this->nodeType == Xml::$Element) {
224 $s .= $this->_nodeName;
225 $»it = $this->_attributes->keys();
226 while($»it->hasNext()) {
232 $s .= $this->_attributes->get($k);
237 if($this->_children->length === 0) {
243 $»it2 = $this->iterator();
244 while($»it2->hasNext()) {
246 $s .= $x->toString();
248 if($this->nodeType == Xml::$Element) {
250 $s .= $this->_nodeName;
255 public function __call($m, $a) {
256 if(isset($this->$m) && is_callable($this->$m))
257 return call_user_func_array($this->$m, $a);
258 else if(isset($this->»dynamics[$m]) && is_callable($this->»dynamics[$m]))
259 return call_user_func_array($this->»dynamics[$m], $a);
260 else if('toString' == $m)
261 return $this->__toString();
263 throw new HException('Unable to call «'.$m.'»');
273 static function __start_element_handler($parser, $name, $attribs) {
274 $node = Xml::createElement($name);
275 while(list($k, $v) = each($attribs)) $node->set($k, $v);
276 Xml::$build->addChild($node);
279 static function __end_element_handler($parser, $name) {
280 Xml::$build = Xml::$build->getParent();
282 static function __character_data_handler($parser, $data) {
283 if((strlen($data) === 1 && htmlentities($data) != $data) || htmlentities($data) == $data) {
284 Xml::$build->addChild(Xml::createPCData(htmlentities($data)));
287 Xml::$build->addChild(Xml::createCData($data));
290 static function __default_handler($parser, $data) {
291 Xml::$build->addChild(Xml::createPCData($data));
294 static function parse($str) {
295 Xml::$build = Xml::createDocument();
296 $xml_parser = xml_parser_create();
297 xml_set_element_handler($xml_parser, (isset(Xml::$__start_element_handler) ? Xml::$__start_element_handler: array("Xml", "__start_element_handler")), (isset(Xml::$__end_element_handler) ? Xml::$__end_element_handler: array("Xml", "__end_element_handler")));
298 xml_set_character_data_handler($xml_parser, (isset(Xml::$__character_data_handler) ? Xml::$__character_data_handler: array("Xml", "__character_data_handler")));
299 xml_set_default_handler($xml_parser, (isset(Xml::$__default_handler) ? Xml::$__default_handler: array("Xml", "__default_handler")));
300 xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0);
301 xml_parser_set_option($xml_parser, XML_OPTION_SKIP_WHITE, 0);
302 $isComplete = Xml::$xmlChecker->match($str);
304 $str = ("<doc>" . $str) . "</doc>";
306 if(1 !== xml_parse($xml_parser, $str, true)) {
307 throw new HException("Xml parse error (" . ((xml_error_string(xml_get_error_code($xml_parser)) . ") line #") . xml_get_current_line_number($xml_parser)));
309 xml_parser_free($xml_parser);
314 Xml::$build = Xml::$build->_children[0];
315 Xml::$build->_parent = null;
316 Xml::$build->_nodeName = null;
317 Xml::$build->nodeType = Xml::$Document;
321 static function createElement($name) {
323 $r->nodeType = Xml::$Element;
324 $r->_children = new _hx_array(array());
325 $r->_attributes = new Hash();
326 $r->setNodeName($name);
329 static function createPCData($data) {
331 $r->nodeType = Xml::$PCData;
332 $r->setNodeValue($data);
335 static function createCData($data) {
337 $r->nodeType = Xml::$CData;
338 $r->setNodeValue($data);
341 static function createComment($data) {
343 $r->nodeType = Xml::$Comment;
344 $r->setNodeValue($data);
347 static function createDocType($data) {
349 $r->nodeType = Xml::$DocType;
350 $r->setNodeValue($data);
353 static function createProlog($data) {
355 $r->nodeType = Xml::$Prolog;
356 $r->setNodeValue($data);
359 static function createDocument() {
361 $r->nodeType = Xml::$Document;
362 $r->_children = new _hx_array(array());
365 function __toString() { return $this->toString(); }
368 Xml::$Element = "element";
369 Xml::$PCData = "pcdata";
370 Xml::$CData = "cdata";
371 Xml::$Comment = "comment";
372 Xml::$DocType = "doctype";
373 Xml::$Prolog = "prolog";
374 Xml::$Document = "document";
376 Xml::$xmlChecker = new EReg("\\s*(<\\?xml|<!DOCTYPE)", "mi");