Java - XHTML文档上的SAX解析器

时间:2009-08-16 13:01:15

标签: java exception xhtml sax entityreference

我正在尝试为从Web下载的XHTML文档编写SAX解析器。起初我遇到了doctype声明的问题(我从here发现这是因为W3C故意阻止了对DTD的访问),但我修正了:

XMLReader reader = parser.getXMLReader();
reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);

然而,现在我遇到了第二个问题。当SAX解析器到达XHTML文档中嵌入的某些Javascript时会引发异常:

    <script type="text/javascript" language="JavaScript">
function checkForm() {
answer = true;
if (siw && siw.selectingSomething)
    answer = false;
    return answer;
}//
</script>

具体来说,解析器在到达&amp;&amp; s时会抛出错误,因为它期望实体引用。确切的例外是:

`org.xml.sax.SAXParseException: The entity name must immediately follow the '&' in the entity reference.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:198)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:177)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:391)
at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1390)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEntityReference(XMLDocumentFragmentScannerImpl.java:1814)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3000)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:624)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:486)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:810)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:740)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:110)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1208)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:525)
at MLIAParser.readPage(MLIAParser.java:55)
at MLIAParser.main(MLIAParser.java:75)`

我怀疑(但我不知道)如果我没有禁用DTD那么我就不会得到这个错误。那么,如何避免DTD错误并避免实体引用错误?

干杯,

皮特

3 个答案:

答案 0 :(得分:3)

您尝试解析的(X)HTML不是有效的XML(否则您将无法获得SAX解析错误)。并且,双&符号(“&&”)证实了这一点。这意味着它本身不能使用普通的XML解析器来解析文档。

您可以使用一些工具,例如TagSoup,它们将生成正确的SAX事件(您可以像以前一样使用相同的SAX / XML解析代码),但TagSoup将负责映射形式不佳的-HTML事件到正确的SAX / XML事件。

答案 1 :(得分:1)

我认为您应该将脚本内容放在CDATA部分中,例如http://www.w3schools.com/TAGS/tag_script.asp给出以下示例:

<script type="text/javascript"><![CDATA[
document.write("Hello World!")
//]]></script>

答案 2 :(得分:0)

NekoHTML也可能会为您解决此问题,您将其用作XMLReader。

如果您正在使用SAX过滤器,在遇到&lt; script&gt;的startElement后,您也可能会插入CDATA events,尽管这可能与解析器有关,因为并非所有解析器都支持{{ 3}}