使用libxml保留HTML实体

时间:2012-04-08 12:26:00

标签: html-entities libxml2

我正在编写一个方法来解析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中存在的唯一实体是引号,例如’和{{1}当我写出节点的HTML内容时,我想保留它。

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

1 个答案:

答案 0 :(得分:3)

事实证明,问题是libxml在内部使用UTF-8(在xmlsoft上的Encodings Support中解释),它将所有HTML字符实体转换为UTF-8字符,因此当输出HTML时将离开这些是转换后的UTF-8字符。

该解决方案也出现在xmlsoft的编码部分,在'Default Supported Encodings'下:

  

libxml2有一组用于以下编码的默认转换器(位于encoding.c中):

     
      
  1. 默认支持UTF-8(空处理程序)
  2.   
  3. UTF-16,无论是小端还是大端
  4.   
  5. ISO-Latin-1(ISO-8859-1)涵盖大多数西方语言
  6.   
  7. ASCII,主要用于保存
  8.   
  9. HTML,用于将UTF-8转换为ASCII的特定处理程序,使用HTML预定义实体,例如& copy;版权符号。
  10.   

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

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

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