XSLT基礎編: xsl:sortでソート処理

2007年08月19日(日)更新


■xsl:sort要素でソート処理を指定する

さらら: ねぇ、たけち。で、xsl:sortってなんなの?

たけち: for-each要素で指定したノードについて処理を繰り返すことを定義したね。

さらら: えぇ。

たけち: この繰り返し処理をする前に、xsl:sortで、選択したノードをソートできるんだ。

さらら: へぇ〜、そうなの。。。で、ソートって?

たけち: .....(^ ^; たとえば、ある指定した要素の内容の値の順序に並べることだよ。

さらら: そっか。(^ ^; じゃあ、年代順とか、作者の名前順に並べ替えたりできるのね。


■xsl:sort要素の書き方

さらら: そうだね。それがわかれば、さっそく書き方を見ておこう。

xsl:sort要素の書き方

さらら: 空要素として書くのね。

たけち: そうだね。で、select="ソートキーを示す式"で指定されたキーの順番に並ぶんだね。

さらら: order="ascending | descending"って何?

たけち: あっ、これは、キーの値の昇順に並べ替えるのか降順にするのか、を指定するんだ。
ascending --- 昇順
descending --- 降順
なんだよ。この属性を省略すると、昇順にソートされるんだ。

さらら: ふぅ〜ん。

たけち: じゃあ、そろそろ具体的な例を考えてみようか。前回xsl:for-eachのところで扱ったXMLデータとXSLスタイルシートをもとにするね。作者の名前順に並べ替えてみよう。

さらら: はい。


■xsl:sortで作者の名前順に並べ替え

さらら: 確認のために、xsl:fo-eachで扱ったXMLデータとXSLスタイルシートを見ておこう。

XMLデータ例: 万葉集第1巻・第2巻抜粋

<?xml version="1.0" encoding="Shift_JIS" ?>

<manyosyu>
<poem pno="8">
  <pno>8</pno>
  <poet>額田王(ぬかたのおおきみ)</poet>
  <yomi>熟田津(にきたつ)に船(ふな)乗りせむと月待てば潮もかなひぬ今は漕(こ)ぎ出(い)でな</yomi>
</poem>

<poem pno="20">
  <poet>額田王(ぬかたのおおきみ)</poet>
  <yomi>茜(あかね)さす 紫野行き標野(しめの)行き 野守(のもり)は見ずや 君が袖振る</yomi>
</poem>

<poem pno="28">
  <poet>持統天皇(じとうてんのう)</poet>
  <yomi>春過ぎて 夏来たるらし 白妙(しろたえ)の 衣干したり 天(あめ)の香具山(かぐやま)</yomi>
</poem>

<poem pno="37">
  <poet>柿本人麻呂(かきのもとのひとまろ)</poet>
  <yomi>見れど飽かぬ 吉野の川の 常滑(とこなめ)の 絶ゆることなく またかへり見む</yomi>
</poem>

<poem pno="113">
  <poet>額田王(ぬかたのおおきみ)</poet>
  <yomi>み吉野(よしの)の 玉(たま)松(まつ)が枝(え)は はしきかも 君が御言(みこと)を 持ちて通(かよ)はく</yomi>
</poem>

<poem pno="137">
  <poet>柿本人麻呂(かきのもとのひとまろ)</poet>
  <yomi>秋山に 落つる黄葉(もみちば) しましくは な散り乱ひそ 妹があたり見む</yomi>
</poem>

</manyosyu>

XSLTスタイルシート例: for-eachを使って万葉歌をテーブル表示

<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
   <html>
   <head>
   <title>たのしいXML: XSLTスタイルシート例(for-eachで歌のリストを表示)</title>
   <link rel="stylesheet" type="text/css" href="manyo.css" />
   </head>

   <body>
   <p align="center"><font color="navy">万葉集第1巻抜粋: for-eachで歌のリストを表示</font></p>

   <table border="1" width="600" align="center">
      <tr>
         <th width="40%">歌人</th>
         <th>歌</th>
      </tr>

   <xsl:apply-templates />

   </table>

   </body>
   </html>
</xsl:template>


<xsl:template match="manyosyu">

<xsl:for-each select="poem">
      <tr>
         <td><xsl:value-of select="poet" /></td>
         <td><xsl:value-of select="yomi" /></td>
      </tr>
</xsl:for-each>


</xsl:template>

</xsl:stylesheet>

さらら: これに、「作者名(poet)の順番」に並ぶように、xsl:sort要素を追加するのね。

たけち: そうなんだね。この場合、xsl:sort要素を含むxsl:for-each要素は次のように書けばいいんだよ。

XSLTスタイルシート例: for-eachとsortを使って作者名順に表示
テンプレート部分
<xsl:template match="manyosyu">

<xsl:for-each select="poem">
   <xsl:sort select="poet" />
      <tr>
         <td><xsl:value-of select="poet" /></td>
         <td><xsl:value-of select="yomi" /></td>
      </tr>
</xsl:for-each>


</xsl:template>

さらら: あら、これだけ?

たけち: そう。簡単だね。念のためにXSLTスタイルシート全体を載せておくね。

XSLTスタイルシート例: for-eachを使って万葉歌をテーブル表示

<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
   <html>
   <head>
   <title>たのしいXML: XSLTスタイルシート例(for-eachで歌のリストを表示)</title>
   <link rel="stylesheet" type="text/css" href="manyo.css" />
   </head>

   <body>
   <p align="center"><font color="navy">万葉集第1巻抜粋: for-eachで歌のリストを表示</font></p>

   <table border="1" width="600" align="center">
      <tr>
         <th width="40%">歌人</th>
         <th>歌</th>
      </tr>

   <xsl:apply-templates />

   </table>

   </body>
   </html>
</xsl:template>


<xsl:template match="manyosyu">

<xsl:for-each select="poem">
   <xsl:sort select="poet" />
      <tr>
         <td><xsl:value-of select="poet" /></td>
         <td><xsl:value-of select="yomi" /></td>
      </tr>
</xsl:for-each>


</xsl:template>

</xsl:stylesheet>

たけち: じゃあ、このXSLTスタイルシートを"sort.xsl"というファイルにして、実際にどうなるか見てみようね。次のテキストをクリックしてみて。あっ、そうそう。いつもと同じように、XMLデータの2行目は
<?xml-stylesheet type="text/xsl" href="sort_1.xsl"?>
として、"poem16_1.xml"というファイルを作成しているからね。

万葉集第1巻抜粋のXMLファイル poem16_1.xml(上記説明のXSL適用)

poem16_1.xmlの表示結果

さらら: あっ、作者ごとにまとまって表示されたわ。。。。xsl:for-eachとxsl:sortってこう使うのね・・・わかったわ。

たけち: よかった。じゃ。今回はここまでね。

さらら: ありがと。

→次回はxsl:number-その1です。。。(^ ^;


■補足: xsl:sortだけの指定方法■

※ここでの例としては、xsl:for-eachの子要素としてxsl:sortを使いましたが、単純にソートだけをするのでしたら、xsk:for-each要素を使わなくてもできます。

xsl:sort要素は、xsl:apply-templates要素の子要素としても出現させることができます。ですから、上記の例に関しては、つぎのようなXSLTスタイルシートを書くことで同じ結果を得ることができます。

【sort_2.xsl】 xsl:sortを使って作者名(poet)でソート

<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <html>
  <head>   <title>たのしいXML: XSLTスタイルシート例(xsl:sortで歌人名でソート)</title>
  <link rel="stylesheet" type="text/css" href="manyo.css" />
  </head>

  <body>
  <p align="center"><font color="navy">万葉集第1巻抜粋: xsl:sortで歌人名でソート</font></p>

  <table border="1" width="600" align="center">
    <tr>
      <th width="40%">歌人</th>
      <th>歌</th>
    </tr>

  <xsl:apply-templates select="manyosyu/poem">
    <xsl:sort select="poet" />
  </xsl:apply-templates>

  </table>
  </body>
  </html>
</xsl:template>

<xsl:template match="poem">
    <tr>
      <td><xsl:value-of select="poet" /></td>
      <td><xsl:value-of select="yomi" /></td>
    </tr>
</xsl:template>

</xsl:stylesheet>

こちらの方が見た目はすっきりしていますね。いちおう、念のためにこのXSLTスタイルシートを"sort_2.xsl"というファイルにして、実際にどうなるか見ておきますね。いつもと同じように、XMLデータの2行目は
<?xml-stylesheet type="text/xsl" href="sort_2.xsl"?>
として、"poem16_2.xml"というファイルにしています。

万葉集第1巻抜粋のXMLファイル poem16_2.xml(上記説明のXSL適用)

poem16_2.xmlの表示結果