rendered paste body<?phpclass node{ protected $name; protected $attr; protected $data; protected $child; public function __construct($name, $attr = array(), $data = '') { $this->name = $name; $this->attr = $attr; $this->data = $data; $this->child = array(); } public function add($node) { $this->child[] = $node; } public function attr($k) { return $this->attr[$k]; } public function __get($k) { foreach($this->child as $v) if($v->name == $k) return $v; return null; } public function asXML() { $xml = ''; $xml .= '<' . $this->name; foreach($this->attr as $k => $v) $xml .= ' ' . $k . '="' . htmlentities($v) . '"'; $xml .= '>'; $xml .= htmlentities($this->data); foreach($this->child as $n) $xml .= $n->asXML(); $xml .= '</' . $this->name . '>'; return $xml; }}class parser{ protected $token; public function v() { array_shift($this->token); } public function parse($data) { preg_match_all('/<([^>]*)>([^<]*)/si', $data, $this->token, PREG_SET_ORDER); $this->root = null; $this->parse_helper(null); return $this->root; } function parse_helper($parent) { while(1) { if(!count($this->token)) break; elseif($this->token[0][1]{0} === '?') { $this->v(); } elseif($this->token[0][1]{0} === '/') { return; } elseif(preg_match('/^([a-z_]+)(.*)/si', $this->token[0][1], $match)) { $name = $match[1]; $attr = array(); if(preg_match_all('/([a-z_]+)="(.*?)"/', $match[2], $amatch, PREG_SET_ORDER)) foreach($amatch as $v) $attr[$v[1]] = html_entity_decode($v[2]); $data = html_entity_decode($this->token[0][2]); $node = new node($name, $attr, $data); $parent ? $parent->add($node) : $this->root = $node; $this->v(); $this->parse_helper($node); $this->v(); } else throw new Exception('unrecognized token'); } }}?>