C++中的HTML清理

3

是否有可用的C++(或者可能是C)函数/类/库,其唯一目的是清理可能包含HTML的字符串?

我找到了很多用于在C#或其他更常用于Web应用程序的语言中进行清理的源代码,但在C++中没有找到任何内容。

如果找不到现成的解决方案,我将尝试实现自己的函数,但我认为经过充分测试的解决方案会更好。

编辑>关于我的需求的一些更精确的说明:

我从键盘获取文本输入,并在将其用作javascript函数调用参数之前对其进行清理。该javascript运行在已加载的html页面中,并通过库(Navi)显示为纹理。因此,我使用的javascript函数将简单地获取给定的文本,将P标签放在文本周围,并将其注入到类似于以下方式的div中:

text_display.innerHTML += text_to_add;

无论是用于这个功能还是其他的功能,我都需要在将文本发送到网页之前对其进行净化。在输入到Chromium之前它必须被净化。


为什么你要用C++来实现一个Web应用程序? - Edward Z. Yang
我不是在手动编写代码。我使用一个库,可以从HTML/JavaScript/CSS生成纹理。我目前从C++应用程序中的字符串调用一些带有参数的页面JavaScript。这个字符串是通过键盘输入的,所以在注入代码之前需要进行清理。 - Klaim
意思是“注入文本”,而不是代码。 - Klaim
5个回答

6

HTML Tidy 是使用 C 语言编写的,但几乎每种语言/平台都有相应的绑定,包括 C++


我不太确定你的意思,你是建议我从Tidy中使用一些代码吗? - Klaim
2
@Klaim HTML的净化理想情况下是一个两步过程 - 首先确保标记符合规范并符合规范。其次是剥离HTML。如果我们尝试在一次通行中完成所有操作,我们必须考虑到HTML可以被破坏的无数种方式,并且仍然可以被浏览器解析/执行。如果您将潜在的标记通过类似于HTML Tidy的东西运行,则会得到如此干净和规范化的结果,以至于您可以安全地将其与简单的白名单一起运行。 - Rex M
感谢您提供的详细信息,我会尝试一下。 - Klaim

1
你可以使用{{link1:libxml2的xmlEncodeSpecialChars}}。

有趣,我会尝试一下。我看到的问题是仅为了进行清理而添加如此“大”的依赖项。但如果它运行良好,我可以尝试隔离代码并将其用于我的项目。 - Klaim

1
你在这里提出了相当复杂的问题。 在你能得到一个好的回答之前,你需要明确你想从输入中“解析”出什么。例如,你可以查找任何“<”字符,并将它们转换为其他内容,这样它们就不会被任何HTML解析器解析。
或者,你可以搜索如下模式:<和>后跟</>模式。(请原谅空格,我必须把它放在这里,以便HTML解析器不会解析它)。然后,你还需要查找“<单一元素标记/>”。
你实际上可以查找有效/已知的HTML标记并将其去除。
因此,问题变成了哪种方法对你的解决方案正确?要知道,如果你制作一个简单的解析器,你可能会将包含大于号和小于号符号的有效文本剥离掉。
因此,这是我的答案。
如果您想简单地删除任何类似HTML的样式文本,我建议使用正则表达式引擎(PCRE),并使用它来解析您的输入,并删除所有匹配的字符串。这可能是最简单的解决方案,但它需要您获取和构建PCRE,并且有一些GPL问题需要您注意,以便适用于您的项目。解析可能非常容易实现,并且运行速度很快。
第二个选项是通过遍历缓冲区来执行此操作,查找开放的HTML字符(<),然后解析直到第一个空格,然后开始遍历,查找关闭的HTML字符(>),然后再次开始遍历,根据刚刚解析的内容查找匹配的CLOSING标记。(比如说,它是一个DIV标记,您要查找/DIV。)
我有代码在STL HTML解析器中执行此操作,但是也有许多问题需要考虑。例如,您需要处理实体代码,像IMG、P和BR这样的单元素标记,等等。

如果你想查看一些非常好的 C 代码,可以去看一下 ClamAV 项目。他们有一个 HTML 解析器,可以将所有标签从页面中剥离出来,并留下仅有的文本内容。(除此之外还有其他功能...) 在文件 libclamav\htmlnorm.c 中,可以找到一个很好的“缓冲区漫步”和解析示例。虽然它不是最快的,但确实有效。最新版的 ClamAV 可能在 HTML 解析器中绑定了太多的东西,以至于可能难以理解。如果是这样,可以回到早期版本,例如 .88.4 版本。只是请注意旧代码库中的错误,其中有一些是好的。

希望这能有所帮助。


我对我的需求进行了一些精确的说明。我将尝试您最后的建议,希望我能够足够地隔离代码。 - Klaim
似乎你只需要“过滤”<和>字符……所以,只需编写一个简单的解析器来删除它们!唯一的问题是这些字符可能在合法输入中被使用,所以你需要澄清,如果确实是这种情况,那么你手头的问题就会变得更加严重。我很愿意帮助你解决这个问题,因为我喜欢C / C ++,但现在却被困在了C#的世界里,这将是一个不错的项目。 :) - LarryF
在考虑制作自己的解决方案之前,我会先尝试这里提出的解决方案,因为它似乎是一个复杂的问题(该条目可能也包含JavaScript...)。然后我会考虑你的帮助。无论如何,问题现在似乎很清楚了吧?如果你想的话,你已经可以开始着手解决了。我开始着手解决这个问题,并发现这是一个复杂的问题,网站应用程序运行在 C# 和 ROR 上已经解决了这个问题。现在我需要一个等效的健壮的C++解决方案。 - Klaim

0
使用Qt的QWebkit来解析HTML树。然后用它输出结果。这样可以清理一下HTML代码。

这不是有点过度了吗?QT不是我项目的依赖项,仅为此添加它似乎不是一个好主意... - Klaim

-1

这篇文章几个小时前发布的。它只是一篇关于正则表达式的文章,但恰好包含了你想要的内容 :) 我认为这篇文章也可能会引起你的兴趣。


2
嗯...你的第一个链接是一篇写于近一年前的文章。也许“几个小时”是口误?;-) - Head Geek
哈哈,我实际上是指几个小时前在SO上发布的。我想我应该解释得更清楚 - 但再次原谅我,因为当时土耳其时间是凌晨4点,我已经苦苦挣扎了数小时,试图编写一个压缩程序 :) - Dunya Degirmenci
这些正则表达式存在已知的漏洞。而且,我怀疑你不想将它加载到 PCRE 中。 - Edward Z. Yang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接