我正在编写一个方法来解析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字符替换,这让我怀疑它是一个解析问题,但我不确定。
答案 0 :(得分:3)
事实证明,问题是libxml在内部使用UTF-8(在xmlsoft上的Encodings Support中解释),它将所有HTML字符实体转换为UTF-8字符,因此当输出HTML时将离开这些是转换后的UTF-8字符。
该解决方案也出现在xmlsoft的编码部分,在'Default Supported Encodings'下:
libxml2有一组用于以下编码的默认转换器(位于encoding.c中):
- 默认支持UTF-8(空处理程序)
- UTF-16,无论是小端还是大端
- ISO-Latin-1(ISO-8859-1)涵盖大多数西方语言
- ASCII,主要用于保存
- HTML,用于将UTF-8转换为ASCII的特定处理程序,使用HTML预定义实体,例如& copy;版权符号。
醇>
它还建议使用像UTF8Toisolat1
'这样的转换函数将libxml函数返回的值转换为另一种编码。
解决方案是使用UTF8ToHtml()
函数转换HTML输出,该函数将非ASCII字符替换为相关的HTML实体(例如’
或‘
)。这似乎使HTML标记<
和>
字符不受影响,这与我尝试使用htmlEncodeEntities()
时不同,后者将其替换为<
和>
。
使用UTF8ToHtml()
时我没有解决的一件事是如何确定为输出缓冲区分配多少内存,因为用实体替换单个字符会增加HTML字符串的长度,所以你可以不要只使用输入HTML的长度。我只是分配了两倍大小的输入缓冲区(我想这应该足够我的所有用例),然后使用实际的长度(通过UTF8ToHtml()
中的指针参数返回),但我不是确定是否有更好的方法来做到这一点。