2011-07-28 60 views
4

我正在爲XML文件的後處理編寫Java應用程序。 這些XML文件來自語義媒體註釋的RDF導出,因此它們具有rdf/xml語法。禁用在JDOM/DOM中解析XML實體

我的問題如下: 當我讀取xml文件時,文件中的所有實體都被解析爲它們在Doctype中指定的值。例如,在文檔類型我有

<!DOCTYPE rdf:RDF[ 
<!ENTITY wiki 'http://example.org/smartgrid/index.php/Special:URIResolver/'> 
.. 
]> 

和在根元素

<rdf:RDF 
xmlns:wiki="&wiki;" 
.. 
> 

這意味着

<swivt:Subject rdf:about="&wiki;Main_Page"> 

變得

<swivt:Subject rdf:about="http://example.org/smartgrid/index.php/Special:URIResolver/Main_Page"> 

我已經使用JDOM和試圖標準的Java DOM。 我認爲與此有關的代碼是標準DOM:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
     factory.setExpandEntityReferences(false); 
     factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); 

和JDOM

SAXBuilder builder = new SAXBuilder(); 
    builder.setExpandEntities(false); //Retain Entities 
    builder.setValidation(false); 
    builder.setFeature("http://xml.org/sax/features/resolve-dtd-uris", false); 

但實體是在整個XML文檔沒有少得到解決。 我錯過了什麼嗎?搜索小時數只讓我看到'ExpandEntities'命令,但它們似乎不起作用。

任何暗示的高度讚賞:)

回答

0

我相信,如果驗證(功能http://xml.org/sax/features/validation)是真實的它覆蓋setExpandEntities(false)。嘗試通過將該功能設置爲false來禁用驗證。

0

我發現了像this one這樣的各種提示,說你不能關閉屬性中的實體擴展。我不知道該怎麼表明這並不難看。例如,可能使用EntityResolver會引入一個「null」DTD - 將「wiki」的擴展定義爲「&wiki;」。似乎有更好的辦法!

4

我建議JDOM FAQ:

[http://www.jdom.org/docs/faq.html#a0350]

如何保持DTD加載?即使關閉驗證,解析器也會嘗試加載DTD文件。

即使關閉驗證,XML解析器在默認情況下也會加載外部DTD文件,以解析DTD以獲取外部實體聲明。 Xerces具有關閉名爲「http://apache.org/xml/features/nonvalidating/load-external-dtd」的行爲的功能,如果您知道您使用的是Xerces,則可以在構建器上設置此功能。

builder.setFeature(
    "http://apache.org/xml/features/nonvalidating/load-external-dtd", false); 

如果你使用另一種解析器像深紅,最好的辦法是建立能解決DTD沒有實際讀取的分割文件的EntityResolver的。

import org.xml.sax.*; 
import java.io.*; 

public class NoOpEntityResolver implements EntityResolver { 
    public InputSource resolveEntity(String publicId, String systemId) { 
    return new InputSource(new StringBufferInputStream("")); 
    } 
} 
在構建器

則...

builder.setEntityResolver(new NoOpEntityResolver()); 

有一個缺點這種方法。文檔中的任何實體都將被解析爲空字符串,並且會實際消失。如果您的文檔包含實體,您需要設置ExpandEntities(false)代碼並確保EntityResolver僅抑制DocType。