Java中是否有一个验证HTML的解析器实现?

4
我需要在Java中解析HTML 4。理想情况下,我希望它是SAX兼容的实现。
我知道有很多Java的HTML解析器,但是它们似乎都进行了“整理”。换句话说,它们会纠正格式不正确的HTML。我不想要这样。
我的要求是:
  1. 不整理。
  2. 如果输入文档是无效的HTML,则解析应该失败。
  3. 文档应该可以针对HTML DTD进行验证。
  4. 解析器可以生成SAX2事件。
是否有符合这些要求的库?

如果解析器不整理,它就无法创建 DOM 树;有效的 HTML 文档可能不是有效的 XML 文档(例如,考虑所有那些没有相应闭合标签的 <p> 标签)。 - jdigital
它可以像<p/> XML元素一样触发SAX事件,对吗? - johnstok
它怎么知道关闭标签丢失了呢? - jdigital
4个回答

2
我认为 Jericho HTML解析器 至少可以满足你的一个核心要求(“如果输入文档是无效的HTML,则解析应该失败。”),因为它至少会告诉你是否存在不匹配的标签或其他有害的HTML缺陷,并且你可以根据这些信息选择是否失败。
尝试在这个Jericho格式演示中输入无效的HTML,并注意页面底部的“解析器日志”:

http://jerichohtmlparser.appspot.com/samples/FormatSource.jsp

所以,是的,这个程序正在整理标签,但至少它会告诉你 - 你可以通过在源代码中设置 net.htmlparser.jericho.Logger(例如 WriterLogger 或其他你自己创建的更具体的 Logger)来获取这些信息,然后根据日志输出的错误进行处理。以下是一个小例子:
    Source source=new Source("<a>I forgot to close my link!");
    source.setLogger(myListeningLogger);

    source.getSourceFormatter().writeTo(new NullWriter());
    // myListeningLogger has now had all the HTML flaws written to it

在上面的例子中,使用字符串 'StartTag at (r1,c1,p0) missing required end tag' 调用了记录器的 info() 方法,该字符串相对易于解析,您始终可以决定拒绝记录任何比调试更糟糕的消息的 HTML - 实际上,Jericho 将几乎所有错误记录为 'info' 级别,只有一些错误记录为 'warn' 级别(您可能会想创建一个小分支,将严重性调整为您关心的内容)。 Jericho 可在 Maven 中央库中获得,这总是一个好迹象。

http://mvnrepository.com/artifact/net.htmlparser.jericho/jericho-html

祝你好运!

2
你可以在这里找到一些HTML解析器HTML Parsers。我记不太清了,但我想TagSoup会解析文件而不进行更正...

TagSoup是一个符合SAX规范的Java解析器,它不会解析良好格式或有效的XML文件,而是解析在实际应用中找到的HTML文件...很遗憾无法解析。 - johnstok
它确保结构良好的结果:标签将被嵌套得当,默认属性将出现在适当位置等等。 - adrian.tarau
如果它能够填充默认属性,这意味着它解析了DTD...但不清楚如果文档未经验证是否会失败。 - adrian.tarau
另外还要看一下javax.swing.text.html.parser.Parser,它似乎可以进行DTD验证。protected void endTag(boolean omitted) { handleText(stack.tag);if (omitted && !stack.elem.omitEnd()) { error("end.missing", stack.elem.getName()); } else if (!stack.terminate()) { error("end.unexpected", stack.elem.getName()); }} - adrian.tarau

1
你可能想要查看http://lobobrowser.org/cobra.jsp。他们有一个纯Java实现的网络浏览器(Lobo)。他们将解析器组件(Cobra)单独提取出来供使用。我不确定它是否符合你对“无整理”要求的需求,但值得一看。当我在探索纯Java网络浏览器时,我偶然发现了它。

0
你可以尝试继承javax.swing.text.html.parser.Parser并实现handleXXX()方法。看起来它不会尝试修复XML。更多信息请参见API

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