[英]How to avoid a SAXParseException using Xerces when HTML file includes mdash?
我正在使用 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
構建的,我收到異常:
Caused by: org.xml.sax.SAXParseException: The entity "mdash" was referenced, but not declared. at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:239) at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:283) at com.sun.org.apache.xpath.internal.jaxp.XPathExpressionImpl.evaluate(XPathExpressionImpl.java:291)
此消息也打印到標准輸出:
[Fatal Error] :20:43: The entity "mdash" was referenced, but not declared.
我怎樣才能避免這個異常?
HTML 文件是從 XML 的 XSLT 轉換創建的。 我認為我不一定需要它是一個—
,我不確定。 HTML 將顯示在 Java Swing 應用程序中。
我很難判斷我的具體實現中有哪些信息與這個問題相關。 如果需要更多信息,請通過評論告訴我。
因此,我錯誤地認為 HTML 是 XML(根本沒有真正考慮過這一點的結果)。
那么,給定一個 HTML 文件,我該如何解決這個問題?
—
與等價物。 HTML 是從 XSLT 轉換創建的,是否可以將樣式表設置為用等效的數字符號替換 mdash?問題是,如果提交給 Xerces 的文檔沒有帶有 mdash 聲明的 DTD,那么它就不是格式良好的 XML 文檔——必須聲明所有實體。 HTML 有一組 HTML 處理器需要知道的“內置”實體,這些實體應該在 DTD 中。
沒有 DTD 的最簡單的解決方法是將 mdash 替換為其等效的數字( —
或—
)
文件頭中的正確 DTD 應包含所有必要的實體聲明,如果您的文件格式正確,則解析器將遵守此信息。
如果有可能 HTML 格式不正確,我建議使用 TagSoup 庫來解決這個問題。 它讀取輸入並嘗試生成有效的 XHTML 作為輸出,從不報告任何解析錯誤,只是嘗試使用內置啟發式方法修復它們。 我能夠成功處理來自網絡的非常損壞的 HTML 並對其執行 XPath 查詢(似乎這就是您所需要的)。
我想我找到了針對我的具體情況的問題。 HTML 文件是使用 XSLT 從 XML 文件生成的。 通過改變線路:
<xsl:output method="html" />
到:
<xsl:output method="xml" />
轉換並沒有創建—
實體。 然后可以使用 Xerces 解析輸出文件。
我不確定這是否“正確”,但它似乎可以在 Swing 中顯示。
鑒於 HTML 不是 XML,我認為您在嘗試使用 XML 解析器解析 HTML Transitional 時可能會發現很多問題。 但如果您的 HTML 實際上是格式良好的 XML,則 mdash 和其他實體通常在 DTD 中定義。 確保您的解析器具有文檔的 DTD,它應該沒問題。
面對這種問題,我通過JTidy運行 (X)HTML。 JTidy 將接受一個與 HTML 或 XML 類似的輸入,並在給定適當的選項的情況下將其轉換為適合所有常用 XML 工具處理的格式良好的 XML。
這為我省去了處理所有可能出現的特殊情況和極端情況的麻煩。 弄清楚如何連接輸入和輸出以及使用哪些選項需要一次性的努力; 之后,It Just Works™。
這不是您使用mdash
特定問題的解決方案 - 但我懷疑這無論如何都不是您的最后一個問題。
您可以啟用功能“ http://apache.org/xml/features/continue-after-fatal-error ”在未知實體的情況下不拋出異常。 但這仍然會發出警告:
documentBuilderFactory.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);
瞧!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.