array('href', 'title'),
'img' => array('src', 'alt', 'width', 'height', 'style'),
);
private $parser;
private $started;
protected $out;
function __construct() {
$this->parser = xml_parser_create('utf-8');
xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false);
xml_set_object($this->parser, $this);
xml_set_element_handler($this->parser, 'startElement', 'endElement');
xml_set_character_data_handler($this->parser, 'characters');
}
function __destruct() {
xml_parser_free($this->parser);
}
public function parse($text) {
if (xml_parse($this->parser, ''.$text.'') !== 1) {
$code = xml_get_error_code($this->parser);
throw new ParsingError(xml_error_string($code), $code, $this->parser);
}
return $this->out;
}
protected function startElement($parser, $name, $attrs) {
if ($name == 'root') {
$this->started = true;
$this->out = '';
return;
}
if (!in_array($name, self::$allowedElements)) {
throw new ParsingError("{$name} есть недопустимый элемент.", 0, $parser);
}
if (array_key_exists($name, self::$allowedAttributes)) {
$allowedAttrs = self::$allowedAttributes[$name];
} else {
$allowedAttrs = null;
}
$out = '<' . $name;
foreach ($attrs as $attr => $value) {
if (is_null($allowedAttrs) OR !in_array($attr, $allowedAttrs)) {
throw new ParsingError("{$attr} есть недопустимый аттрибут для элемента {$name}.", 0, $parser);
}
$out .= ' ' . $attr . '="' . htmlspecialchars($value, ENT_COMPAT, 'UTF-8') . '"';
}
$out .= '>';
$this->out .= $out;
}
protected function endElement($parser, $name) {
if ($name == 'root') {
return;
}
$this->out .= "{$name}>";
}
protected function characters($parser, $data) {
$this->out .= htmlspecialchars($data, ENT_NOQUOTES, 'UTF-8');
}
}
class ParsingError extends Exception {
public $row;
public $col;
public function __construct($message, $code, $parser) {
parent::__construct($message, $code);
$this->col = xml_get_current_column_number($parser);
$this->row = xml_get_current_line_number($parser);
}
}
// test code below
?>
parse($_POST['test']);
echo '', $text, '
';
} catch (ParsingError $e) {
echo '', htmlspecialchars($e->getMessage()), '
';
echo "Строка {$e->row}, столбец {$e->col}.
";
}
}
?>