15

変数値に依存するモードでテンプレートを適用したいと考えています。

<xsl:variable name="mode" select="@attribute"/>
<xsl:apply-templates mode="{$mode}"/>

スタイルシートをコンパイルできないというエラーが表示されます。mode の値は QName である必要がありますが、「{$mode}」です。

変数に依存するモードを使用する可能性はありますか?

4

3 に答える 3

9

式に基づいて特定のモードを使用する必要がある唯一のオプションは、使用することです

<xsl:choose>
   <xsl:when test="@attribute = 'foo'">
      <xsl:apply-templates mode="bar"/>
   </xsl:when>
   <xsl:otherwise>
      <xsl:apply-templates/>
   </xsl:otherwise>
</xsl:choose>

または と同じxsl:ifです。mode属性値自体は、XSLT 1.0 では a である必要があり、QNameXSLT 2.0 では aまたはor ' のQNameような特別なトークンを使用できます。ただし、実行時に値を計算することはできません。#current#defaultmode

于 2012-09-06T11:57:22.850 に答える
5

modeは、属性値テンプレート (AVT) の有効な候補ではありません。あなたは単にこれを行うことはできません.

XSLT 2.0 仕様から:

[定義: リテラル結果要素の属性など、属性値テンプレートとして指定された属性では、式を中括弧 ({}) で囲むことにより、式を使用できます]。

modeは仕様で AVT として指定されていないため、これを行うことはできません。

于 2012-09-06T11:34:45.007 に答える
2

スタイルシートをコンパイルできないというエラーが表示されます。mode の値は QName である必要がありますが、「{$mode}」です。

変数に依存するモードを使用する可能性はありますか?

いいえ、これはどの XSLT バージョン (1.0、2.0、または 3.0) でもサポートされていません。

実際に高次関数 (HOF) をエミュレートしようとしているので、FXSLの基本原理を使用して XSLT 1.0 でこれを行うことができます。

FXSL 1.x は、HOF をサポート/エミュレートする純粋な XSLT 1.0 で記述されたテンプレートのライブラリです。

これらの原則に基づく完全なソリューションを次に示します

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:f="http://fxsl.sf.net" exclude-result-prefixes="f">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

   <f:inc/>
   <f:double/>

 <xsl:variable name="vModeInc" select="document('')/*/f:inc[1]"/>
 <xsl:variable name="vModeDouble" select="document('')/*/f:double[1]"/>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="/*">
  <nums>
    <xsl:apply-templates select="$vModeInc">
      <xsl:with-param name="pNodes" select="node()"/>
    </xsl:apply-templates>
  </nums>
==============
  <nums>
    <xsl:apply-templates select="$vModeDouble">
      <xsl:with-param name="pNodes" select="node()"/>
    </xsl:apply-templates>
  </nums>
 </xsl:template>

 <xsl:template match="f:inc">
   <xsl:param name="pNodes"/>
   <xsl:apply-templates select="$pNodes" mode="incr"/>
 </xsl:template>

 <xsl:template match="f:double">
   <xsl:param name="pNodes"/>
   <xsl:apply-templates select="$pNodes" mode="double"/>
 </xsl:template>

 <xsl:template match="num" mode="incr">
  <num><xsl:value-of select=".+1"/></num>
 </xsl:template>

 <xsl:template match="num" mode="double">
  <num><xsl:value-of select=".*2"/></num>
 </xsl:template>
</xsl:stylesheet>

この変換が次の XML ドキュメントに適用される場合:

<nums>
  <num>01</num>
  <num>02</num>
  <num>03</num>
  <num>04</num>
  <num>05</num>
  <num>06</num>
  <num>07</num>
  <num>08</num>
  <num>09</num>
  <num>10</num>
</nums>

必要な正しい結果が生成されます--nums/num指定された変数に応じて、使用可能な 2 つのモードのいずれか (それぞれ) で要素が処理されます -- $vModeInc(各値に 1 が加算される) または$vModeDouble(各値が 2 倍される):

<nums>
   <num>2</num>
   <num>3</num>
   <num>4</num>
   <num>5</num>
   <num>6</num>
   <num>7</num>
   <num>8</num>
   <num>9</num>
   <num>10</num>
   <num>11</num>
</nums>
==============
  <nums>
   <num>2</num>
   <num>4</num>
   <num>6</num>
   <num>8</num>
   <num>10</num>
   <num>12</num>
   <num>14</num>
   <num>16</num>
   <num>18</num>
   <num>20</num>
</nums>
于 2012-09-06T12:05:48.677 に答える