我的目標是分割包含各種內容(約2至15 GB)爲多個XML文件一個大的,單獨的XML文件,每片含某個實體類型,例如稍後可以通過SQL數據庫導入。我目前正在使用Saxon-EE版本9.5.1.2J,但其他任何XSL處理器都可以,如果它可以快速可靠地完成工作。使用單個XSL流存儲到一個大的XML文件分割成多個文件
以下是我已經想通了:
- 撒克遜似乎是XSLT 3.0的事實上的標準處理器,而猛禽XML服務器似乎是另一個(更貴)的選擇。其他XSL處理器通常只支持XSLT 1.0。
- 大文件可以使用XSLT 3.0流進行處理,以便整個文件不需要適應內存。注意:此功能僅在Saxon Enterprise Edition中可用。
- 您可以使用
<xsl:result-document>
寫輸出到不同的文件,但你可以不多次使用它在相同樣式表來寫同一個文件(顯然不是線程安全的)。 <xsl:for-each-group>
與基團的由顯然是不可流傳送的<xsl:stream>
只能包含一個<xsl:iterate>
塊,這是確定。但是:在該迭代塊內部,只能訪問當前節點和一個子節點的屬性(即使<xsl:for-each>
在該節點上工作)。如果嘗試訪問第二個節點的值,則會出現「SXST0060:多個子表達式使用輸入流」錯誤。<xsl:apply-templates>
<xsl:stream>
(而不是迭代)需要模式streamer(如下圖所示)。但是,流只能像迭代一樣消耗一次 - 否則,您也會收到錯誤「SXST0060:多個子表達式消耗輸入流」。
我的結論是,目前可用的XSL處理器需要使用多個<xsl:stream>
標籤寫入到不同的文件,這在實踐中意味着掃描輸入文件過大多次爲每個輸出文件。這是即使如此,編寫不同實體的相同輸出文件作爲解決辦法的時候,因爲這是不可能的「消費」同一個輸入流不止一次:
<xsl:mode name="s" streamable="yes"/>
<xsl:template match="/">
<xsl:stream href="input.xml">
<xsl:apply-templates mode="s" select="content/articles"/>
</xsl:stream>
<xsl:stream href="input.xml">
<xsl:apply-templates mode="s" select="content/articles/article/authors"/>
</xsl:stream>
</xsl:template>
它涉及到一個地步提取用解釋和更加複雜的命令行腳本從一個大的XML文件中的不同實體更快 - 從而使XSLT慢的和無用的比較:(
我希望有一個基於XSLT 3.0解決方案在那裏,工作原理預計多次掃描輸入文件?我沒有看到阻止這種用例的XSLT的基本技術限制。
XSLT將比我們的解釋腳本快得多,如果按預期工作更方便。恕我直言,它不是XSL流在xsl:iterate期間訪問多個單一(子)節點的根本限制。也許撒克遜可以在未來的版本中支持它,或者有一款已經支持它的處理器?能夠在一次運行中拆分和轉換大型XML文檔將是其他更低級別方法的主要優勢。 – lastzero