Сохранение объектов HTML с помощью libxml

Я пишу метод для анализа строки HTML, запроса и получения некоторых узлов, а затем вывода HTML для этих узлов.

Я использую libxml, и мне удалось загрузить и проанализировать входной HTML-код и вывести строку HTML для нужных мне узлов, за исключением того, что я хочу сохранить любые объекты HTML, и libxml, похоже, преобразует их в связанные с ними символы UTF-8.

Вот что у меня получилось (код является частью проекта Objective-C):

NSString *HTMLString = ...
NSData *documentData = [HTMLString dataUsingEncoding:NSUTF8StringEncoding];

//Create the document
xmlDocPtr doc = htmlReadMemory([documentData bytes],
                               [documentData length],
                               "",
                               NULL,
                               HTML_PARSE_NOWARNING | HTML_PARSE_NOERROR);

//Get the node I want to output
xmlNodePtr node = ...

//Create the node buffer and fill it with the node content
xmlBufferPtr nodeBuffer = xmlBufferCreate();
htmlNodeDump(nodeBuffer, doc, node);

...

Это отлично выгружает HTML-содержимое узла, за исключением того, что символьные сущности преобразуются в символы UTF-8 — единственные сущности, которые существуют во входном HTML, — это кавычки, такие как ’ и ‘, которые я хочу сохранить при записи HTML-контент узла.

Я просмотрел документы libxml, относящиеся к синтаксическому анализу HTML и функциям дерева HTML, и не могу найти никакой информации о сущностях HTML. Я также не уверен, что это делается во время синтаксического анализа или вывода. Я пытался просто вывести содержимое узла, используя xmlNodeGetContent(), и сущности также были заменены соответствующими символами UTF8, что заставляет меня подозревать, что это проблема синтаксического анализа, но я не уверен.


person Alex Rozanski    schedule 08.04.2012    source источник


Ответы (1)


Оказывается, проблема в том, что libxml работает внутри с UTF-8 (объяснено в Поддержка кодировок в xmlsoft) , который преобразует все сущности символов HTML в символы UTF-8, поэтому при выводе HTML они останутся как преобразованные символы UTF-8.

Решение также представлено в разделе кодирования на xmlsoft в разделе «Поддерживаемые кодировки по умолчанию»:

libxml2 имеет набор конвертеров по умолчанию для следующих кодировок (находится в encoding.c):

  1. UTF-8 поддерживается по умолчанию (нулевые обработчики)
  2. UTF-16, как с прямым, так и с обратным порядком байтов
  3. ISO-Latin-1 (ISO-8859-1), охватывающий большинство западных языков.
  4. ASCII, полезен в основном для сохранения
  5. HTML, специальный обработчик преобразования UTF-8 в ASCII с предопределенными объектами HTML, такими как знак авторского права.

Также рекомендуется использовать функции преобразования, подобные UTF8Toisolat1, для преобразования значений, возвращаемых функциями libxml, в другую кодировку.

Решение состоит в том, чтобы преобразовать вывод HTML с помощью функции UTF8ToHtml(), которая заменит не-ASCII символов с их соответствующими объектами HTML (такими как &rsquo; или &lsquo;). Это, кажется, оставляет символы HTML-тега < и > нетронутыми, в отличие от того, когда я пытался использовать htmlEncodeEntities(), который заменяет их на &lt; и &gt;.

Одна вещь, которую я не решил при использовании UTF8ToHtml(), заключалась в том, как определить, сколько памяти выделить для выходного буфера, поскольку замена отдельных символов сущностями увеличит длину строки HTML, поэтому вы не можете просто использовать входные HTML-коды. длина. Я просто выделил удвоенный размер входного буфера (которого, как мне кажется, должно быть достаточно для всех моих вариантов использования), а затем использовал фактическую используемую длину (возвращается через параметр указателя в UTF8ToHtml()), но я не уверен, есть ли лучший способ сделать это.

person Alex Rozanski    schedule 08.04.2012