2013-04-25 83 views
1

我有一個搖籃腳本下面的代碼片段(語法的Groovy/Java的的組合):解析任何文件類型爲XML

File file = new File(filename) // Filename is being read from console 
def content = file.getText() 
Document document = DOMBuilder.parse(new StringReader(content), false, false) 

的問題是,我試圖解析XML文件,但帶有xconf擴展名(例如file.xconf)。出於某種原因或其他,當我嘗試上面的代碼,我收到以下錯誤消息(控制檯):

java.io.FileNotFoundException: <full_path>/file.dtd (No such file or directory) 

的路徑是正確的,但我注意到了擴展突然被改爲.dtd。 我在文件中注意到該文件的.dtd版本的引用,但我希望解析器忽略該文件(並停止驗證,這就是爲什麼DOMBuilder.parse()的第二個參數爲false)。我可以改變這種行爲能夠成功解析文件嗎?

注意:如果可能,我還希望能夠對(任何)其他文件擴展名執行相同的操作。

在此先感謝!

回答

1

試試這個:

import groovy.xml.* 
import org.w3c.dom.Document; 
import org.xml.sax.InputSource; 

Document parseWithoutDTD(Reader r, boolean validating=false, boolean namespaceAware=true) { 
    FactorySupport.createDocumentBuilderFactory().with { f -> 
    f.namespaceAware = namespaceAware 
    f.validating = validating 
    f.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); 
    f.newDocumentBuilder().with { db -> 
     db.parse(new InputSource(r)) 
    } 
    } 
} 

Document d = new File(filename).withReader { r -> 
    parseWithoutDTD(r) 
} 
+0

迄今爲止工作完美。謝謝! – 2013-04-25 09:03:42

+0

這是一個附帶問題:我注意到這個例子中,namespaceAwareness處於打開狀態。但是,我如何在這裏聲明命名空間?我完全不知道。你可以做這樣的事情:'f.declareNamespace(...)',然後爲方法添加一個額外的參數? – 2013-04-25 10:47:13

+0

解析時不聲明名稱空間,它在XML文檔中聲明 – 2013-04-25 10:48:31

1

file.xconf xml必須在XML中定義了DTD引用。打開文件並檢查。

DOM解析器默認根據與XML關聯的DTD驗證XML。如果您不想驗證,則將驗證模式設置爲false。檢查DomBuilder API。

其他選項是定義XML中的DTD路徑,以便從任何地方訪問它,或者您也可以註冊解析器。我忘了怎麼做,但你可以查找。

+0

它確實定義了一個DTD參考,但 - 你可以在問題中看到 - 驗證模式已被設置爲false。 – 2013-04-25 08:36:35

+0

您正在使用哪種DOMBuilder實現?即使驗證設置爲false,它仍會嘗試加載DTD。我查看了我的代碼並找到了它的EntityResolver。您可以通過實施EntityResolver來創建自己的解析器。 – 2013-04-25 08:48:50

+0

我正在使用'groovy.xml.DOMBuilder'。 – 2013-04-25 08:53:45

0

A DTD定義了XML文檔的規則。如果遵循這些規則,則xml文檔將被視爲「valid」。 如果您想忽略DTD文件(例如因爲它不存在),請將解析的驗證模式設置爲false。

+0

我知道DTD是什麼,但感謝您花時間澄清。正如前面的回答所評論的,驗證模式已經設置爲false(在問題代碼中可以看到)。 – 2013-04-25 08:40:22