2005-04-19

使えそうな XSLT Tips

XPathには、substring-before(string, string) [引用: http://www.w3.org/TR/xpath#function-substring-before より] substring-after(string, string) [引用: http://www.w3.org/TR/xpath#function-substring-after より] という文字列関数がある。この二つの関数は、どちらも2番目の引数に指定した文字列が1番目の引数に指定した文字列内で最初に見つかった場合に、substring-before()関数ならばその文字列よりも前、substring-after()関数ならばその文字列よりも後にある文字列を返すことができる。この二つの関数は、XSLTを記述する際に何かと役に立ち用いることの多い関数であるが、これとは対極的に、ある文字列内である文字列が最後に見つかった場合に、その文字列よりも前或いは後にある文字列を取得したい場合には、次のような名前付きテンプレートを用いると良いだろう。

last-substring-before テンプレート

次のテンプレート記述は、指定文字列の最後から指定文字を検索する。substring-before()関数の最終検索版である。

<xsl:template name="last-substring-before">
  <xsl:param name="p1"/>
  <xsl:param name="p2"/>
  <xsl:if test="contains($p1,$p2)">
    <xsl:value-of select="substring-before($p1,$p2)"/>
    <xsl:if test="contains(substring-after($p1,$p2),$p2)">
      <xsl:value-of select="$p2"/>
    </xsl:if>
    <xsl:call-template name="last-substring-before">
      <xsl:with-param name="p1" select="substring-after($p1,$p2)"/>
      <xsl:with-param name="p2" select="$p2"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>

引数p2に指定した文字列が引数p1に指定した文字列内で最後に見つかった場合に、その文字列よりも前にある文字列を返す。引数p2に指定した文字列が引数p1に指定した文字列内に含まれていない場合は、空の文字列を返す。

例えば、次の例は 1999/04 を返す。

<xsl:call-template name="last-substring-before">
  <xsl:with-param name="p1" select="'1999/04/01'"/>
  <xsl:with-param name="p2" select="'/'"/>
</xsl:call-template>

last-substring-after テンプレート

次のテンプレート記述は、指定文字列の最後から指定文字を検索する。substring-after()関数の最終検索版である。

<xsl:template name="last-substring-after">
  <xsl:param name="p1"/>
  <xsl:param name="p2"/>
  <xsl:choose>
    <xsl:when test="contains($p1,$p2)">
      <xsl:call-template name="last-substring-after">
        <xsl:with-param name="p1" select="substring-after($p1,$p2)"/>
        <xsl:with-param name="p2" select="$p2"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$p1"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

引数p2に指定した文字列が引数p1に指定した文字列内で最後に見つかった場合に、その文字列よりも後にある文字列を返す。引数p2に指定した文字列が引数p1に指定した文字列内に含まれていない場合は、空の文字列を返す。

例えば、次の例は 01 を返す。

<xsl:call-template name="last-substring-after">
  <xsl:with-param name="p1" select="'1999/04/01'"/>
  <xsl:with-param name="p2" select="'/'"/>
</xsl:call-template>