我目前正在編寫一個使用Java 1.6的工具,它彙集了許多XML文件。所有這些文件都被驗證爲DocBook 4.5 DTD(我已經使用xmllint檢查了這一點,並將DocBook 4.5 DTD指定爲--dtdvalid參數),但並非所有文件都包含DOCTYPE聲明。指定DocumentBuilders用於XML解析的DTD?
我每個XML文件加載到DOM執行所需的操作,像這樣:
private Document fileToDocument(File input) throws ParserConfigurationException, IOException, SAXException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
factory.setIgnoringElementContentWhitespace(false);
factory.setIgnoringComments(false);
factory.setValidating(false);
factory.setExpandEntityReferences(false);
DocumentBuilder builder = factory.newDocumentBuilder();
return builder.parse(input);
}
對於這個已經做得很不錯了大多數情況下,我可以用他回到對象瀏覽樹並執行需要的操作,然後將文檔寫回。當我遇到的問題是文件,其中:
- 不要包含DOCTYPE聲明,
- 確實包括在DTD定義的實體(例如& MDASH;/—)。
如果這是個例外,從builder.parse拋出的情況下(...)有消息稱:
[Fatal Error] :5:15: The entity "mdash" was referenced, but not declared.
不夠公平,它沒有聲明。在這個實例中理想的做法是將DocumentBuilderFactory設置爲始終使用DocBook 4.5 DTD,而不管文件中是否指定了其中一個。
我曾嘗試使用DocBook 4.5模式驗證,但發現這與XML產生了許多不相關的錯誤。似乎這個模式在功能上可能不等同於DTD,至少對於這個版本的DocBook規範來說。
我能想到的另一個選項是讀取文件,嘗試並檢測是否設置了文檔類型,然後在實際將XML解析到DOM之前找到沒有文件的情況下設置一個。
所以,我的問題是,有沒有我還沒有看到告訴解析器使用特定的DTD或保證解析收益儘管實體未解決(不只是與emdash一個更聰明的方式,例如,但在任何實體XML - 有很多潛力)?
謝謝,我不知道EntityResolver2接口(只有EntityResolver)。一旦我重載了建議的方法,併爲其他人提供了默認處理,我現在遇到以下錯誤: [致命錯誤] docbookx.dtd:101:9:遞歸實體引用「%dbnotn」。 (參考路徑:%dbnotn - >%dbnotn - >%dbnotn) 基於此,似乎DTD現在至少已被應用,但有其他問題:)。 – xsgordon