<indexterm>の話です.DITAのindextermはDocBookなんかと違って、無限(?)にネストできます.例えば
<indexterm>www
<indexterm>w3
<indexterm>org
</indexterm>
</indexterm>
</indexterm>
<indexterm>w3
<indexterm>org
</indexterm>
</indexterm>
</indexterm>
というような具合です.それではこれをソートするのにどうすればいいのでしょうか?今までいろいろ試行錯誤したのですが、たとえXSLT 2.0であっても単純な<xsl:sort/>ではできないことだけはわかりました.何故かと言うと、「ソートキーの個数が可変」だからです.
以前は、上の例だと、概念的に
[www][w3][org]
という3つの部分からなる固定長の文字列を作っていました.固定長というのはindextermのテキストの後ろにスペースコードをパディングして各部を一定の文字数にしたものです.これをindextermの入れ子分だけ結合して一つの文字列にしてソートキーにしていました.見かけは動くのですが、実は<xsl:sort>ではパディングしたスペースキーは何の役にも立たないことがわかりました.キーとしては読み飛ばしてしまうようです.やっぱりJavaで言えばStringじゃなくてString []をキーにしてソートできなければダメです.
そこで何か手はないものかとWEBを探したのですが、やはり世の中には同じ問題にぶつかっている人はいるもので、相当前のxsl-listに次のようなサンプルコードつきの投稿がありました.sourceforgeのFXSLの作者Dimitre Novatchevのものです.
[xsl] Sorting with unknown number of sort keys (Was: Re: Sort question)
http://www.biglist.com/lists/xsl-list/archives/200303/msg00007.html
http://www.biglist.com/lists/xsl-list/archives/200303/msg00007.html
コードは古くてXSLT1.0の時代のものです.でも中を読んでみて衝撃をうけました.「こりゃいけるんじゃないかい?」
私はXSLT1.0といえばコケにするのが常でしたが、このコードは違いました.XSLTの深淵を垣間見た感じです.やっぱり出来る人は違いますね.試しにSaxon9.3で動かしてみたのですが、なんと2ステップ直しただけで完璧に動きました.スゴイ!
以下にテンポラリツリーをソートした例を示します.実際のindextermとは違いますが、可変個数の<key>を使ってソートすると考えてください.
<xsl:template match="/">
<xsl:variable name="input">
<indexterm>
<key>らいせんすかんりせんようPC</key>
</indexterm>
<indexterm>
<key>らいせんすかんりそふとうぇあ</key>
</indexterm>
<indexterm>
<key>らいせんす</key>
</indexterm>
<indexterm>
<key>らいせんす</key>
<key>すたんどあろんらいせんす</key>
</indexterm>
<indexterm>
<key>らいせんす</key>
<key>さーばーらいせんす</key>
</indexterm>
<indexterm>
<key>らいせんす</key>
<key>でべろぱーらいせんす</key>
</indexterm>
<indexterm>
<key>らいせんす</key>
<key>でべろぱーらいせんす</key>
<key>Visual C++よう</key>
</indexterm>
<indexterm>
<key>らいせんす</key>
<key>でべろぱーらいせんす</key>
<key>Javaよう</key>
</indexterm>
<indexterm>
<key>らいせんすわりつけをへんこうする</key>
</indexterm>
</xsl:variable>
<output>
<!--ここからサンプルのコードを呼び出す-->
<xsl:call-template name="indexSort">
<xsl:with-param name="prmIndexterm" select="$input"/>
</xsl:call-template>
</output>
</xsl:template>
<xsl:variable name="input">
<indexterm>
<key>らいせんすかんりせんようPC</key>
</indexterm>
<indexterm>
<key>らいせんすかんりそふとうぇあ</key>
</indexterm>
<indexterm>
<key>らいせんす</key>
</indexterm>
<indexterm>
<key>らいせんす</key>
<key>すたんどあろんらいせんす</key>
</indexterm>
<indexterm>
<key>らいせんす</key>
<key>さーばーらいせんす</key>
</indexterm>
<indexterm>
<key>らいせんす</key>
<key>でべろぱーらいせんす</key>
</indexterm>
<indexterm>
<key>らいせんす</key>
<key>でべろぱーらいせんす</key>
<key>Visual C++よう</key>
</indexterm>
<indexterm>
<key>らいせんす</key>
<key>でべろぱーらいせんす</key>
<key>Javaよう</key>
</indexterm>
<indexterm>
<key>らいせんすわりつけをへんこうする</key>
</indexterm>
</xsl:variable>
<output>
<!--ここからサンプルのコードを呼び出す-->
<xsl:call-template name="indexSort">
<xsl:with-param name="prmIndexterm" select="$input"/>
</xsl:call-template>
</output>
</xsl:template>
<xsl:template name="indexSort">
<xsl:param name="prmIndexterm" as="document-node()"/>
<xsl:call-template name="hSort">
<xsl:with-param name="pList" select="$prmIndexterm/*"/>
<xsl:with-param name="pFunGT"
select="document('')/*/myFunGT:*[1]"/>
</xsl:call-template>
</xsl:template>
<xsl:param name="prmIndexterm" as="document-node()"/>
<xsl:call-template name="hSort">
<xsl:with-param name="pList" select="$prmIndexterm/*"/>
<xsl:with-param name="pFunGT"
select="document('')/*/myFunGT:*[1]"/>
</xsl:call-template>
</xsl:template>
出力はこんな感じです.
<output>
<indexterm>
<key>らいせんす</key>
</indexterm>
<indexterm>
<key>らいせんす</key>
<key>さーばーらいせんす</key>
</indexterm>
<indexterm>
<key>らいせんす</key>
<key>すたんどあろんらいせんす</key>
</indexterm>
<indexterm>
<key>らいせんす</key>
<key>でべろぱーらいせんす</key>
</indexterm>
<indexterm>
<key>らいせんす</key>
<key>でべろぱーらいせんす</key>
<key>Javaよう</key>
</indexterm>
<indexterm>
<key>らいせんす</key>
<key>でべろぱーらいせんす</key>
<key>Visual C++よう</key>
</indexterm>
<indexterm>
<key>らいせんすかんりせんようPC</key>
</indexterm>
<indexterm>
<key>らいせんすかんりそふとうぇあ</key>
</indexterm>
<indexterm>
<key>らいせんすわりつけをへんこうする</key>
</indexterm>
</output>
<indexterm>
<key>らいせんす</key>
</indexterm>
<indexterm>
<key>らいせんす</key>
<key>さーばーらいせんす</key>
</indexterm>
<indexterm>
<key>らいせんす</key>
<key>すたんどあろんらいせんす</key>
</indexterm>
<indexterm>
<key>らいせんす</key>
<key>でべろぱーらいせんす</key>
</indexterm>
<indexterm>
<key>らいせんす</key>
<key>でべろぱーらいせんす</key>
<key>Javaよう</key>
</indexterm>
<indexterm>
<key>らいせんす</key>
<key>でべろぱーらいせんす</key>
<key>Visual C++よう</key>
</indexterm>
<indexterm>
<key>らいせんすかんりせんようPC</key>
</indexterm>
<indexterm>
<key>らいせんすかんりそふとうぇあ</key>
</indexterm>
<indexterm>
<key>らいせんすわりつけをへんこうする</key>
</indexterm>
</output>