2014-01-08 67 views
0

在將它提供給XSL-Transformer之前,我需要替換XML文件中的某些文本。 這是DOCTYPE標記中的DTD-URL。它指向一個網絡服務器,但我希望它可以離線使用,所以我想將其更改爲指向本地文件的URL。在XSLT之前替換XML中的文本

但是,我不能直接編輯原始XML。我想將文件讀入字符串,在文本上使用String.replaceAll()並將其保存到另一個文件中,然後將其傳遞給Transformer。我已經嘗試過了,但它確實很慢;我正在使用的文件的大小爲ca. 500kiB。

有沒有更好的方法來實現這個目標?

編輯:用於轉換的代碼:

public String getPlaylist(String playlist) { 
    Source source = new StreamSource(library); 
    StreamSource xsl = new StreamSource(getClass().getResourceAsStream("M3Utransformation.xml")); 
    StringWriter w = new StringWriter(); 
    Result result = new StreamResult(w); 
    try { 
     Transformer transformer = TransformerFactory.newInstance().newTransformer(xsl); 
     transformer.setParameter("playlist", playlist); 
     transformer.transform(source, result); 
     return w.getBuffer().toString(); 
    } catch (Throwable t) { 
     t.printStackTrace(); 
     return null; 
    } 
} 
+0

根據W3C的規定,有很多過多的DTD流量,請參閱http://www.w3.org/blog/systeam/2008/02/08/w3c_s_excessive_dtd_traffic/ 這讓人想起這個問題,你真的需要你的dtd嗎? 我會追求並回答這個問題,但是我認爲我會首先要求您提供代碼示例,該示例在未訪問dtd時失敗 – OYRM

+0

要轉換的XML文件不是由我創建的。這是一個iTunes資料庫。我不想搞亂圖書館本身。 – s3lph

+2

大多數XML解析器和至少一些XSLT處理器都有一個API,它允許您編寫和插入代碼,以提供對部分或全部URL/URI的特殊解釋。這可以用來識別DTD請求並返回從您想要的任何位置獲取的輸入流 - 範圍從內存中的字符串到本地文件到文件緩存,具體取決於您想要做多少工作。 這通常被稱爲「DTD解析器」或「實體解析器」,具體取決於您使用哪個API來運行樣式表。 – keshlam

回答

4

您可以創建一個實體解析器,並利用它。

下面的示例使用JAXP的DocumentBuilder和CatalogResolver

public static void main(String[] args) throws ParserConfigurationException, 
     SAXException, IOException, TransformerConfigurationException, TransformerException { 

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
    DocumentBuilder db = dbf.newDocumentBuilder(); 
    db.setEntityResolver(new CatalogResolver()); 

    File src = new File("src/article.xml"); 
    Document doc = db.parse(src); 

    // Here, we execute the transformation 
    // Use a Transformer for output 
    File stylesheet = new File("src/aticle.xsl"); 
    TransformerFactory tFactory = TransformerFactory.newInstance(); 
    StreamSource stylesource = new StreamSource(stylesheet); 
    Transformer transformer = tFactory.newTransformer(stylesource); 

    DOMSource source = new DOMSource(document); 
    StreamResult result = new StreamResult(System.out); 
    transformer.transform(source, result); 
} 

創建目錄屬性文件,並將其放置在你的classpath CatalogManager.properties必須是一個名字,看見CatalogManager API documentation

定義一個目錄XML文件,將你的屬性文件指向它。從 http://www.xml.com/pub/a/2004/03/03/catalogs.html你可以找到一個非常簡單的目錄XML文件:

<?xml version="1.0" encoding="UTF-8"?> 
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> 
    <public publicId="-//OYRM/foo" uri="src/bar.dtd"/> 
</catalog> 

通過以上的catalog.xml和CatalogManager.properties,你最終會解析爲publicId引用「 - // OYRM/foo」換該URI的src/bar.dtd XML的公共包含解析:

http://xerces.apache.org/mirrors.cgi#binary

爲分解的話題更完整的處理讀Tom White's article from XML.com

轉換器應用程序是從爪哇軌跡中爲可擴展樣式表語言轉換生成的> Crimbed>Transforming Data with XSLT

+0

我將如何將'Document doc'交給變壓器? – s3lph

+0

編輯自己弄明白:'new DOMSource(doc)'。非常感謝你。 – s3lph

+1

我編輯了上述內容以完成轉換並將數據發送到System.out ...很高興您獲得了@the_Seppi,但我想我會完成編輯。 – OYRM