XSLで遊んでみた

ちょっとバカな日記。
XSLでのプログラミングの勉強のため、今月の出費をXML形式のファイルで保存し、日ごとの出費額と、月全体の出費額をXSLTでHTMLに変換するテストプログラムを書いてみた。
XSLについてきちんと調べる前はXSLではいろいろな計算ができるものかと思っていた。足し算とか、掛け算は組み込みで準備されていて、任意の関数も定義できるものかと思っていた。だけど、実際は変換処理の流れしか定義できないことを知って、ちょっと愕然とした。というのも、ループ処理とか分岐処理ができるので、もっと複雑なこともできるものと思っていたからである。しかも、計算はXSLの機能ではなく、XPathの機能で行われることを知ってさらに驚いた(たいした関数は用意されて無いけど)。というのも、XPathXMLファイル内の要素、属性などを指定するだけのものかと思っていたからだ。自分のXML関連の知識のなさに今さらながら情け無いと思った。
でも、ちょっと複雑な処理を行いたい場合はどうするんだろう。ブラウザに表示するなら、XMLファイルからは値だけを取り出して、JavaScriptで計算をするって手もあるけど。ブラウザじゃない場合はどうやって関数の定義をするのかなぁ?そもそも関数の定義ができるのかなぁ。
ちなみに、ためしに書いたプログラムが以下。最初のファイルが出費データ(一部)で、2個目のファイルがXSLファイル。ソースを貼り付けると見にくくなるけど貼ってみたかったので、貼ってみた。

<?xml version="1.0" encoding="SHIFT_JIS"?>
<expenditure>
  <day date="2005-07-25">
    <item type="meal">
      <name>昼飯</name>
      <price unit="yen">488</price>
    </item>
    <item type="play">
      <name>友達との遊び</name>
      <price unit="yen">2750</price>
    </item>
  </day>

  <day date="2005-07-26">
    <item type="meal">
      <name>昼飯</name>
      <price unit="yen">500</price>
    </item>
    <item type="meal">
      <name>夜食</name>
      <price unit="yen">190</price>
    </item>
    <item type="meal">
      <name>晩飯</name>
      <price unit="yen">290</price>
    </item>
  </day>
</expenditure>
<?xml version="1.0" encoding="SHIFT_JIS"?>
<!--
  日にちと、その日に消費した金額を表にして表示する。
  最後に総消費額を表示する。
  -->
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

  <xsl:template match="/">
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="expenditure">
    <html>
      <table border="1">
        <tr><td>日</td><td>値段(円)</td></tr>
        <xsl:for-each select="./day">
          <tr>
            <td><div style="font-weight:bold">
              <xsl:value-of select="@date"/>
            </div></td>
            <td><xsl:value-of select="sum(./item/price)"/></td>
          </tr>
        </xsl:for-each>

        <xsl:for-each select=".">
          <tr>
            <td><div style="color:red;font-weight:bold">
              合計
            </div></td>
            <td>
              <xsl:value-of select="sum(./day/item/price)"/>
            </td>
          </tr>
        </xsl:for-each>
      </table>
    </html>
  </xsl:template>
</xsl:stylesheet>