html-entities - 使用 libxml 保留 HTML 实体

标签 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 中存在的唯一实体是引号,例如 ,当我写出节点的 HTML 内容时我希望保留它。

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

最佳答案

事实证明,问题在于 libxml 在内部使用 UTF-8(在 xmlsoft 上的 Encodings Support 中进行了解释),它将所有 HTML 字符实体转换为 UTF-8 字符,因此在输出 HTML 时会将它们保留为转换后的 UTF-8 字符。

该解决方案也在 xmlsoft 的编码部分中的“默认支持的编码”下提供:

libxml2 has a set of default converters for the following encodings (located in encoding.c):

  1. UTF-8 is supported by default (null handlers)
  2. UTF-16, both little and big endian
  3. ISO-Latin-1 (ISO-8859-1) covering most western languages
  4. ASCII, useful mostly for saving
  5. HTML, a specific handler for the conversion of UTF-8 to ASCII with HTML predefined entities like © for the Copyright sign.

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

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

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

关于html-entities - 使用 libxml 保留 HTML 实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10062780/

相关文章:

c - 如何修复 "I/O warning : failed to load external entity "file.xml“”? libxml2,macOS

python - lxml:clean_html 用 div 替换 html 标签?

ruby - Nokogiri 无法使用 UTF-16 声明输出 XML(理解和解决)

PHP:解码 Html 实体

html - 在标签中使用 Html 实体

url - 传输换行符 "\n"

c - 为什么 libxml2 在 C/C++ 代码中到处都使用 "BAD_CAST"?

c++ - 在 libxml2 和 xmlsec 中禁用调试输出

html - 如何转义 HTML 实体?

php - "&reg"被转换为 "®"