XSLT2.0の感覚

Written byがいすと

3 結果ツリーのリサイクル

私にとって一番大きなXSLT1.0からの変更点です。リレーショナルデータベースや、文書内の相互参照を解決するには、1)参照をすべて拾い上げて、2)得られた参照を元の場所へ戻す、という二段階が必要です。このように、段階を踏む処理をするには、 XSLTスタイルシートで結果として構成されたツリーに対して、さらに処理を与える必要があります。ところが、これまでは一つのXSLTスタイルシートで多段階の処理をすることはできませんでした;XSLTの処理結果(result tree fragment)が代入不能だったからです。

XSLT2.0では、処理結果を変数に格納する際、node-setとして処理されます。したがって、このnode-set変数にmatchするようなパターンを書くことで、多段階の処理が一つのスタイルシートで可能になります。

<xsl:template match="/">
    <!-- 1段階目の処理 -->
    <xsl:variable name="SecondTree">
        <xsl:call-template name="MakeSecondTree"/>
    </xsl:variable>
    <!-- 2段階目の処理 -->
    <xsl:call-template name="ProcessSecondTree">
        <xsl:with-param name="tree" select="$SecondTree"/>
    </xsl:call-template>
</xsl:template>

<xsl:template name="MakeSecondTree">
    <xsl:apply-templates select="/" mode="firstProcess"/>
</xsl:template>

<xsl:template match="/" mode="firstProcess">
    <!-- 1段階目の処理の内容 -->
</xsl:template>

<xsl:template name="ProcessSecondTree">
    <xsl:param name="tree"/>
    <xsl:apply-templates select="$tree" mode="secondProcess"/>
</xsl:template>

<xsl:template match="/" mode="secondProcess">
    <!-- 2段階目の処理の内容 -->
</xsl:template>

2段階で処理するためのフレームワークです。各処理は名前付きのテンプレートとし、その中でマッチング処理をしています。各処理のマッチング処理はmode属性を使用することで区別しています。

Node-setを再利用するための独自拡張にはXT(※)のxt:node-set()やSAXONのsaxon:nodeSet()などがありました。今後は標準化されたxslのnode-setが用いられることになるでしょう。

XTのホームページ

追記:Xalanにもxalan:nodeset()があります。情報提供いただいた吟雅氏に感謝。