2009-08-16 84 views
0

我正在嘗試爲從Web下載的XHTML文檔編寫SAX解析器。起初,我是有DOCTYPE聲明一個問題(我從here,這是因爲W3C特意禁止訪問DTD發現),但我固定的搭配:Java - XHTML文檔中的SAX解析器

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

不過,現在我遇到第二個問題。當它到達一些JavaScript嵌入在XHTML文檔中的SAX解析器拋出異常:

<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錯誤並避免實體引用錯誤?

乾杯,

皮特

+0

我沒有關閉DTD,而是下載了它,並將其作爲嵌入資源添加到我的軟件中;那麼,當解析器需要它的時候,我將它的本地/下載/緩存的DTD拷貝給它,而不是從互聯網上獲取它。我認爲這比完全禁用DTD處理更好。 – ChrisW 2009-08-16 13:27:48

回答

4

的(X)HTML你正在試圖解析不是有效的XML(否則你不會得到一個SAX解析錯誤)。而且,雙和號(「&&」)證實了這一點。這意味着它本身不能使用簡單的XML解析器來解析文檔。

您可以使用的工具,如TagSoup,它會生成適當的SAX事件(您可以使用與以前相同的SAX/XML解析代碼),但TagSoup會負責映射不完整的HTML事件適當的SAX/XML事件。

1

我覺得你應該放在CDATA節的腳本內容,例如http://www.w3schools.com/TAGS/tag_script.asp給出了下面的例子:

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

關於這方面的一些額外信息:xhtml通常用作mimetype text/html而不是application/xhtml + xml,就像它應該一樣,這就是爲什麼像這樣的錯誤是可能的。另見http://www.w3.org/TR/2002/NOTE-xhtml-media-types-20020801/ – wds 2009-08-17 10:00:50

0

NekoHTML可能會解決這個問題對你的好,你把它作爲一個XMLReader。

如果您使用的是SAX過濾器,您可能還可以插入CDATA events你遇到的startElement爲<腳本>後,雖然並不是所有分析器支持LexicalHandler features,可能是解析器依賴。