Java - XHTML 文档上的 SAX 解析器
我正在尝试为从网上下载的 XHTML 文档编写一个 SAX 解析器。起初我遇到了 doctype 声明的问题(我从 这里这是因为 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>
具体来说,解析器在到达 && 时会抛出错误,因为它需要实体引用。确切的例外是:
`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错误并避免实体引用错误呢?
干杯,
皮特
I'm trying to write a SAX parser for an XHTML document that I download from the web. At first I was having a problem with the doctype declaration (I found out from here that it was because W3C have intentionally blocked access to the DTD), but I fixed that with:
XMLReader reader = parser.getXMLReader();
reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);
However, now I'm experiencing a second problem. The SAX parser throws an exception when it reaches some Javascript embedded in the XHTML document:
<script type="text/javascript" language="JavaScript">
function checkForm() {
answer = true;
if (siw && siw.selectingSomething)
answer = false;
return answer;
}//
</script>
Specifically the parser throws an error once it reaches the &&'s, as it's expecting an entity reference. The exact exception is:
`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)`
I suspect (but I don't know) that if I hadn't disabled the DTD then I wouldn't get this error. So, how can I avoid the DTD error and avoid the entity reference error?
Cheers,
Pete
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您尝试解析的 (X)HTML 不是有效的 XML(否则您不会收到 SAX 解析错误)。并且,双与号(“
&&
”)证实了这一点。这意味着您不能单独使用纯 XML 解析器来解析文档。您可以使用一些工具,例如 TagSoup,它将生成正确的 SAX事件(您可以使用与以前相同的 SAX/XML 解析代码),但 TagSoup 将负责将格式不良的 HTML 事件映射到正确的 SAX/XML 事件。
The (X)HTML you are trying to parse is not valid XML (otherwise you wouldn't be getting a SAX parsing error). And, a double-ampersand ("
&&
") confirms that. That means that on its own, you can't use use a plain XML parser to parse the document.There are tools you can use, such as TagSoup, which will generate proper SAX events (you can use the same SAX/XML parsing code as before), but TagSoup will take care of mapping the poorly-formed-HTML events to proper SAX/XML events.
我认为你应该将脚本内容放在 CDATA 部分中,例如 http:// www.w3schools.com/TAGS/tag_script.asp 给出了以下示例:
I think you're supposed to put the script content in a CDATA section, for example http://www.w3schools.com/TAGS/tag_script.asp gives the following example:
NekoHTML 可能也会为您解决这个问题,您可以将它用作 XMLReader。
如果您使用 SAX 过滤器,您还可以插入 CDATA 事件 在遇到
NekoHTML will probably fix this for you as well, you use it as a the XMLReader.
If you're using a SAX filter, you might also be able to insert CDATA events after you encounter a startElement for <script>, although that might be parser-dependent as not all parsers support the LexicalHandler features.