Jintrick.netagenda2002年09月アーカイブ → 2002年09月12日

XSLTにおけるNMTOKENS型属性の扱い

カレントノードが、例えば次のようなh2要素であった場合を考える。

<h2 class="foo bar baz">heading text</h2>

このとき、class名である「foo」、「bar」、「baz」それぞれについて、これらをspan要素として生成したいとする。

まずこのように、名前付きテンプレート(forEachNMTOKENS)にclass属性値をパラメータとして渡しつつ呼び出す。名前付きテンプレート「forEachNMTOKENS」は後述。

<xsl:call-template name="forEachNMTOKENS">
 <xsl:with-param name="NMTOKENS" select="normalize-space(@class)" />
</xsl:call-template>

各class属性値が、一つ以上の空白記号で区切られている場合考慮に入れ、最初にこのテンプレートを呼び出す際に、class属性値を正規化(normalize-space(@class))している点に注意。

<xsl:template name="forEachNMTOKENS">
 <xsl:param name="NMTOKENS">arbitrarySTRING</xsl:param>
 <xsl:variable name="dividedNMTOKENS" select="substring-after($NMTOKENS, ' ')" />

 <xsl:if test="$dividedNMTOKENS = ''">
  <!-- 属性値が一つしかない場合は空文字列が返却される -->
  <!-- ここに属性値($NMTOKENS)に関するリテラル結果要素等 -->
  <span><xsl:value-of select="$NMTOKENS" /></span>
 </xsl:if>

 <xsl:if test="$dividedNMTOKENS != ''">
  <!-- 複数存在した場合 -->
  <xsl:variable name="ATTRVALUE" select="substring-before($NMTOKENS, ' ')" />
  <!-- ここに属性値($ATTRVALUE)に関するリテラル結果要素等 -->
  <span><xsl:value-of select="$ATTRVALUE" /></span>
  
  <xsl:call-template name="forEachNMTOKENS">
   <xsl:with-param name="NMTOKENS" select="$dividedNMTOKENS" />
  </xsl:call-template>
 </xsl:if>
</xsl:template>

これで、「foo」、「bar」、「baz」それぞれを内容に持ったspan要素が3つ生成されることになる。

汎用性を持たせるなら、リテラル結果要素の部分をテンプレート呼び出しにしてしまえば良い(筈)。何のテンプレートを呼び出すかは、もう一つ別のパラメータを作り、それで判別。

不便?

XPathで、NMTOKENS型属性の値それぞれをノードとして指定できれば、このようなことをする必要は無いのだけど。というわけで、もしそのようなことが出来るなら、このテンプレートは無価値。

これは何?

例えばこのWeblogのXMLソースにて各記事に「topic="XSLT XPath"」 というような属性を設けておいて:

こういうことしよういうのが狙い。前者はDOMで、後者はXSLTで。


webmaster@jintrick.net
公開: 2002年09月12日
カテゴリ: XSLT