2

我正在编写一种方法来解析 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 时我希望保留它内容。

我查看了与 HTML 解析和 HTML 树函数相关的 libxml 文档,但似乎找不到任何有关 HTML 实体的信息。我也不确定这是否是在解析或输出期间完成的。我确实尝试使用简单地输出节点的内容,xmlNodeGetContent()并且实体也被相应的 UTF8 字符替换,这让我怀疑这是一个解析问题,但我不确定。

4

1 回答 1

3

事实证明,问题在于 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 预定义实体,例如 © 版权标志。

它还建议使用转换函数 'like UTF8Toisolat1' 将从 libxml 函数返回的值转换为另一种编码。

UTF8ToHtml()解决方案是使用将非 ASCII 字符替换为相关 HTML 实体(例如&rsquo;&lsquo;)的函数转换 HTML 输出。这似乎使 HTML 标记<>字符保持不变,这与我尝试用和htmlEncodeEntities()替换它们时不同。&lt;&gt;

使用时我没有解决的一件事UTF8ToHtml()是如何确定为输出缓冲区分配多少内存,因为用实体替换单个字符会增加 HTML 字符串的长度,所以你不能只使用输入 HTML 的长度. 我只是分配了两倍大小的输入缓冲区(我想这对于我的所有用例来说应该足够了),然后使用了实际使用的长度(通过 in 中的指针参数返回UTF8ToHtml()),但我不确定是否有更好的方法来做到这一点。

于 2012-04-08T15:42:54.203 回答