重複データをまとめる

以下のようなxmlがあるとしよう.日付毎にアクセスしたURLを保管したxmlである.

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <access date="2006-06-11">
    <url>http://www.google.co.jp/</url>
    <url>http://www.yahoo.co.jp/</url>
    <url>http://www.asahi.com/</url>
  </access>
  <access date="2006-06-10">
    <url>http://www.asahi.com/</url>
  </access>
  <access date="2006-06-09">
    <url>http://www.yahoo.co.jp/</url>
    <url>http://www.apple.co.jp/</url>
  </access>
  <access date="2006-06-08">
    <url>http://www.google.co.jp/</url>
    <url>http://www.kakaku.com/</url>
  </access>
</root>

この中から,重複がない形でアクセスしたURLの一覧を出力するxsltを作るとこうなる.preceding軸を使って重複データを省いている.カレントのurl要素がそれまでに現れたurl要素と異なっていた場合のみ,テンプレートを適応する.

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

  <xsl:output method="text" encoding="UTF-8"/>

  <xsl:template match="/root">
    <xsl:apply-templates select="access/url[not(.=preceding::url)]"/>
  </xsl:template>

  <xsl:template match="url">
    URL: <xsl:value-of select="."/>
  </xsl:template>
</xsl:stylesheet>

これをSaxon 8.5で実行すると,以下のような結果になる.

URL: http://www.google.co.jp/
URL: http://www.yahoo.co.jp/
URL: http://www.asahi.com/
URL: http://www.apple.co.jp/
URL: http://www.kakaku.com/

直近3日分のみ取り出したい場合は,positionを使って件数を絞る.

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

    <xsl:output method="text" encoding="UTF-8"/>

    <xsl:template match="/root">
        <xsl:apply-templates select="access[position()&lt;=3]/url[not(.=preceding::url)]"/>
    </xsl:template>

    <xsl:template match="url">
        URL: <xsl:value-of select="."/>
    </xsl:template>
</xsl:stylesheet>

実行すると以下の通り.4日前にアクセスしたhttp://www.kakaku.com/は出てこない.

URL: http://www.google.co.jp/
URL: http://www.yahoo.co.jp/
URL: http://www.asahi.com/
URL: http://www.apple.co.jp/