XSLT拡張関数( set )

今週は、XSLTの拡張関数の set の紹介です。
例題として、ノード集合の中から 同じString値を持つものを省いて表示する簡単なXSLを
set:distinct 関数で実現します。

残念なお知らせ

XSLTの拡張関数紹介では、SunのJDKが最初から持っているXSLTエンジンを使うことを
想定していましたが、set関数は、本家の Xalan.jar をダウンロードして使う必要があります。

管理人も、JDKのバグかと思ったのですが、JDK1.6.0_1, JDK1.6.0_3(2008年1月12時点の最新)では、
set:distinct 関数のところで、エラーが出力されてしまい、本家の xalan.jar を組み込むことで、
エラーが解消されました。

管理人は、いつものごとく Maven2 で開発していますので、pom.xml に以下の追記を行いました。 下記を追記すると、他にも依存関係で複数の jar を Maven2 がダウンロードすることがありますが、 xalan-2.7.0.jar 1本だけを アプリの classpath に通せば動作します。

本サイトで紹介している「自作ソフト」→XTransformUI も、xalan-2.7.0.jar を組み込むように
改造しておきましたので、XSLTの動作確認は、XTransfomrUI を 使っていただけると、簡単です。

実行例

早速使い方を見てみましょう。

変換元のXMLは下記とします。

XSLT変換は、下記のように、xsl:for-each 中で、set:distinct を宣言するだけです。
ちなみに、公式サイトのAPIによると distinct関数は static NodeList distinct(NodeList nl);
なので、ノード集合を受け取って、値の重複がないノードリストを返すという仕様です。

出力結果は、以下のようになります。
今回は、xsl:value-of で、ノードの値を表示する代わりに、xsl:copy-of で
set:distinct 関数が返してきたノードをそのまま表示してみました。

属性 no の値を見れば、元のXMLの /data/item ノードで、値が重複しているノードを
取り除いていることが分かると思います。

参考

XSLT拡張関数 set:distinct を使わずに、同じ処理を実現する XSL を紹介しておきます。
ポイントは、preceding-sibling:: 表記なのですが、可読性という観点から見ると、set:distinct
を使うほうが、明らかに読み易いですね。

まとめ

XSLT拡張関数の set を紹介しました。
set関数には、他にも difference(差集合), intersection(積集合)などがありますので、 公式サイトのAPIを見ながら、あれこれ試してみるとよいのではないかと思います。