【问题标题】:How to avoid a SAXParseException using Xerces when HTML file includes mdash?当 HTML 文件包含 mdash 时,如何使用 Xerces 避免 SAXParseException?
【发布时间】:2009-11-27 13:49:26
【问题描述】:

我正在使用 JDK6 中的 Xerces 实现对 HTML 4.0 过渡文档执行 XPath 查询。使用以下代码:

XPath newXPath = XPathFactory.newInstance().newXPath();
XPathExpression xpathExpr = newXPath.compile(expression);
Object xPathResult = xpathExpr.evaluate(inputSource, XPathConstants.NODESET);

inputSource 是从 FileInputStream 构建的,我收到异常:

引起:org.xml.sax.SAXParseException:实体“mdash”被引用,但未声明。 在 com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:239) 在 com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:283) 在 com.sun.org.apache.xpath.internal.jaxp.XPathExpressionImpl.evaluate(XPathExpressionImpl.java:291)

此消息也会打印到标准输出:

[致命错误]:20:43:引用了实体“mdash”,但未声明。

如何避免这个异常?

HTML 文件是从 XML 的 XSLT 转换创建的。我认为我不一定需要它是—,我不确定。 HTML 将显示在 Java Swing 应用程序中。

我很难判断我的具体实现中的哪些信息与此问题相关。如果需要更多信息,请通过 cmets 告诉我。


所以,我误以为 HTML 是 XML(实际上根本没有考虑到这一点)。

那么,给定一个 HTML 文件,我该如何解决这个问题呢?

  • 为解析器提供 HTML 4 的 DTD?
  • — 替换为等效项。 HTML 是通过 XSLT 转换创建的,是否可以将样式表设置为将 mdash 替换为等效的数字符号?
  • 是否有任何库可以在将 HTML 提供给解析器之前对其进行修复?我注意到 JTidy 出于类似目的而被提及。

【问题讨论】:

    标签: java html xml xslt xpath


    【解决方案1】:

    问题在于,如果呈现给 Xerces 的文档没有带有 mdash 声明的 DTD,则它不是格式良好的 XML 文档 - 所有实体都必须声明。 HTML 有一组 HTML 处理器需要知道的“内置”实体,这些实体应该在 DTD 中。

    不带 DTD 的最简单解决方法是将 mdash 替换为等效的数字(——

    【讨论】:

    • XHTML 会出现这个问题吗?
    • 可以定义实体的唯一位置是在 DTD 中。因此,如果文件具有带有 DTD 的 DOCTYPE,Xerces 应该从那里检索实体。
    • 另一个问题是我在大学代理后面工作,查找超时。我不想弄乱代理,是否可以向 Xerces 提供本地 DTD 文件,我可以从 w3c.org 保存相关文件?
    【解决方案2】:

    文件头中正确的 DTD 应该包含所有必要的实体声明,如果您的文件格式正确,那么解析器将遵循此信息。

    如果 HTML 格式不正确,我建议使用 TagSoup 库来解决此问题。它读取输入并尝试生成有效的 XHTML 作为输出,从不报告任何解析错误,只是尝试使用内置的启发式方法修复它们。我能够成功地处理来自网络的非常损坏的 HTML,并对其执行 XPath 查询(看起来这就是你所需要的)。

    【讨论】:

      【解决方案3】:

      我想我找到了针对我的具体情况的问题。 HTML 文件是使用 XSLT 从 XML 文件生成的。通过换行:

      <xsl:output method="html" />  
      

      到:

      <xsl:output method="xml" />
      

      转换未创建&amp;mdash; 实体。然后可以使用 Xerces 解析输出文件。

      我不确定这是否“正确”,但它似乎可以在 Swing 中显示。

      【讨论】:

      • 太糟糕了,我看到这个有点晚了。是的,这也是一个适当且正确的解决方案。如果你可以生成“干净”的 XML,你就不需要 JTidy。
      【解决方案4】:

      鉴于 HTML 不是 XML,我认为您在尝试使用 XML 解析器解析 HTML 过渡时可能会发现很多问题。但如果您的 HTML 实际上是格式良好的 XML,则 mdash 和其他实体通常在 DTD 中定义。确保您的解析器具有文档的 DTD,它应该没问题。

      【讨论】:

        【解决方案5】:

        面对这种问题,我通过JTidy 运行(X)HTML。 JTidy 将接受与 HTML 或 XML 模糊相似的输入,并在适当的选项下将其转换为格式良好的 XML,可以通过所有常用的 XML 工具进行处理。

        这省去了我处理所有可能出现的特殊情况和极端情况的麻烦。一次性搞清楚如何连接输入和输出,以及使用哪些选项;之后,It Just Works™。

        这不是解决您使用 mdash 的具体问题的解决方案——但我怀疑这绝不是您的最后一个问题。

        【讨论】:

          【解决方案6】:

          您可以启用功能“http://apache.org/xml/features/continue-after-fatal-error”以在未知实体的情况下不引发异常。不过,这仍然会发出警告:

          documentBuilderFactory.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);
          

          瞧瞧!

          【讨论】:

            猜你喜欢
            • 2012-01-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-09-10
            • 1970-01-01
            相关资源
            最近更新 更多