Friday, July 3, 2009

Поддержка entity в XML Parser(PHP)

По-умолчанию xml parser не поддерживает символические имена для спец символов(entity), при парсинге XML в котором встречаются такие символы - они отбрасываются. Для того чтобы этого избежать нужно заменить все символические имена на цифровые коды, которые он нормально обрабатывает.

Примерчик:
...

/* replace some named entity
amp|#38
quot|#34
gt|#62
nbsp|#160
lt|#60
iexcl|#161
cent|#162
pound|#163
copy|#169
*/
function replace_entity($document)
{
$search = array (
"'&'",
"'"'",
"'>'",
"' '",
"'<'",
"'¡'",
"'¢'",
"'£'",
"'©'"
);
$replace = array (
"&",
""",
">",
" ",
"<",
"¡",
"¢",
"£",
"©"
);
return preg_replace($search, $replace, $document);
}

function parse($data, $logs)
{
$this->logfile= $logs;
$this->parser = xml_parser_create('UTF-8');
xml_set_object($this->parser, $this);
xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false);
xml_set_element_handler($this->parser, 'tag_open', 'tag_close');
xml_set_character_data_handler($this->parser, 'cdata');
$this->log_all($data."\n");
if (!xml_parse($this->parser, $this->replace_entity($data)))
{
$this->error_code = xml_get_error_code($this->parser);
$this->error_string = xml_error_string($this->error_code);
$this->current_line = xml_get_current_line_number($this->parser);
$this->current_column = xml_get_current_column_number($this->parser);
}
xml_parser_free($this->parser);
}
...


P. S. Полгода - год назад это было так, сейчас может быть уже поддерживает, но решение вполне универсально, так как помогает добавить поддержку новых спецсимволов, если это потребуется.

No comments: