2014-10-06 90 views
2

我有這種樹的大XML文件(6 GB): XSLT 3.0流媒體(撒克遜)

<Report> 
    <Document> 
     <documentType>E</documentType> 
     <person> 
     <firstname>John</firstname> 
     <lastname>Smith</lastname> 
     </person> 
    </Document> 
    <Document> 
     [...] 
    </Document> 
    <Document> 
     [...] 
    </Document> 
    [...] 
</Report> 

如果我申請上有一個XSLT樣式表,我有這樣的錯誤:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

所以我想嘗試新的XSLT 3.0功能:使用Saxon 9.6 EE進行流式傳輸。 我不想在文檔中產生一次流限制。我認爲,我想要做的,是非常接近,在這裏所描述的「突發模式」:http://saxonica.com/documentation/html/sourcedocs/streaming/burst-mode-streaming.html

這裏是我的撒克遜命令行:

java -cp saxon9ee.jar net.sf.saxon.Transform -t -s:input.xml -xsl:stylesheet.xsl -o:output/output.html

這裏是我的XSLT樣式表:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"> 
<xsl:mode streamable="yes" /> 

<xsl:template match="/"> 
    GLOBAL HEADER 
     <xsl:iterate select="copy-of()/Report/Document" > 
      DOC HEADER 
      documentType: <xsl:value-of select="documentType"/> 
      person/firstname: <xsl:value-of select="person/firstname"/> 
      DOC FOOTER 
      <xsl:next-iteration/> 
     </xsl:iterate> 
    GLOBAL FOOTER 
</xsl:template> 

</xsl:stylesheet> 

但我仍然有相同的內存不足錯誤。

謝謝你的幫助!

回答

2

您的copy-of()正在複製上下文項目,該項目是整個文檔。您想要

copy-of(/Report/Document) 

它依次複製每個文檔。或者我傾向於寫它

/Report/Document/copy-of() 

因爲我認爲它使得它更清楚發生了什麼事情。

順便說一句,你不需要xsl:迭代在這裏:xsl:for-每個都會很好地完成這項工作,因爲處理一個Document不依賴於任何以前的文檔的處理。

+0

謝謝! 「/ Report/Document/copy-of()」運行良好。 棘手的是「copy-of(/ Report/Document)」給出了這個錯誤: XPTY0004:不允許多個項目的序列作爲拷貝的第一個參數() – steco 2014-10-07 13:44:38

+0

拷貝函數已在2014年10月2日xslt 3.0工作草案中更改爲接受節點序列,Saxon 9.6已實施此更改。你確定你使用9.6嗎?如果您正在進行流式傳輸,我強烈建議轉移到Saxon 9.6。 – 2014-10-07 16:56:08

+0

哦,你是對的,我點擊了錯誤的下載鏈接。我正在使用Saxon-EE 9.5.1.6J,現在使用Saxon-EE 9.6.0.1J,它正在工作!我有另一個與這種突發模式相關的問題:如果我想在'xsl:iterate'標記中使用'xsl:call-template',我有這個錯誤:'XTSE3430:模板規則被聲明爲流傳播,但它不滿足流傳性規則。 * xsl:呼叫模板在這個撒克遜版本中不是流式傳輸。任何想法來克服複製後的流式約束? – steco 2014-10-07 18:26:52