4

私の目標は、さまざまなコンテンツ (約 2 から 15 GB) を含む大きな単一の XML ファイルを複数の XML ファイルに分割し、それぞれに特定のエンティティ タイプを含め、後で SQL データベースなどにインポートできるようにすることです。私は現在、Saxon-EE バージョン 9.5.1.2Jを使用していますが、高速で信頼性の高いジョブを実行する場合は、他の XSL プロセッサでも問題ありません。

これが私がすでに理解したものです:

  • Saxonは XSLT 3.0 の事実上の標準プロセッサのようですが、Raptor XML サーバーは別の (より高価な) 選択肢のようです。他の XSL プロセッサは通常、XSLT 1.0 のみをサポートします。
  • 大きなファイルはXSLT 3.0 ストリームを使用して処理できるため、ファイル全体がメモリに収まる必要はありません。注: この機能は、Saxon Enterprise Edition でのみ使用できます。
  • を使用<xsl:result-document>して出力を別のファイルに書き込むことはできますが、同じスタイルシートで複数回使用して同じファイルに書き込むことはできません (明らかにスレッドセーフではありません)。
  • <xsl:for-each-group>group-by を使用すると、明らかにストリーミングできませ
  • <xsl:stream>ブロックを1 つ だけ含めることができますが、これで問題ありません。<xsl:iterate>しかし: その iterate ブロック内では、現在のノードと 1 つの子ノードの属性にのみアクセスできます (<xsl:for-each>その 1 つのノードでも機能します)。2 番目のノードの値にアクセスしようとすると、「SXST0060: 複数の部分式が入力ストリームを消費しています」というエラーが発生します。
  • <xsl:apply-templates>inside <xsl:stream>(反復ではなく) モード streamable が必要です (以下に示すように)。ただし、ストリームは iterate のように 1 回しか消費できません。それ以外の場合は、「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 3.0 ベースのソリューションがあることを願っています。このような使用例を妨げる XSLT の基本的な技術的制限は見当たりません。

4

2 に答える 2