2012-03-23 2 views
1

xsl:choose(MSXMLエンジンで使用する)を使用してrtfからノードセット変数を作成することはできますか?<xsl:choose>を使用して結果ツリーフラグメントからノードセット変数を構築する

<xsl:choose> 
    <xsl:when test="function-available('msxsl:node-set')"> 
     <xsl:variable name="colorList" select="msxsl:node-set($std:colorList)"/> 
     <xsl:for-each select="$colorList/color"> 
      tr.testid<xsl:value-of select="@testid"/> { 
       color:<xsl:value-of select="."/>; 
      } 
     </xsl:for-each> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:variable name="colorList" select="$std:colorList"/> 
     <xsl:for-each select="$colorList/color"> 
      tr.testid<xsl:value-of select="@testid"/> { 
       color:<xsl:value-of select="."/>; 
      } 
     </xsl:for-each> 
    </xsl:otherwise> 
</xsl:choose> 

std:colorListはもちろんのツリーフラグメントである:

は、私は、次の構文を持っています。 上記のコードはうまく動作し、コードは2つの選択肢で同じですが、それほど大きくないので問題ありません。
しかし、コードフラグメントを大きくすると、最初にrtfに基づいて変数を宣言してからコードを複製することを避けることができるのだろうかと思います。

<xsl:variable name="colorList"> 
    <xsl:choose> 
     <xsl:when test="function-available('msxsl:node-set')"> 
      <xsl:copy-of select="msxsl:node-set($std:colorList)"/> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:copy-of select="$std:colorList"/> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:variable> 

<xsl:for-each select="$colorList/color"> 
    tr.testid<xsl:value-of select="@testid"/> { 
     color:<xsl:value-of select="."/>; 
    } 
</xsl:for-each> 

のようなもの。しかし、これは正しく動作しません:MSXML約colorListは、ノードセットされていない文句を言い、それはxsl:for-eachで使用することはできません。実施例では、このエラーがcolorList変数にあるため、「コピー」std:colorListの発生しなかったことを

XSL transformation failed due to following error: 
Expression must evaluate to a node-set. 
-->$colorList<--/color 

は注意してください。どうやらこれはxsl解析エラーであり、実行時エラーではありません。
xsl:copy-of以外のものを使用しますか?あるいは、同じことを達成する別の方法がありますか?あなたが疑問に思う場合

次のように、std:colorList内容は以下のとおりです。XSLT 1.0で残念ながら

<std:colorList> 
    <color testid="111">#FF0000</color> 
    <color testid="999">#FFFF00</color> 
</std:colorList> 

答えて

3

XSLとき、:変数が指示ではなく、select属性が含まれていた、結果は常にRTFです。したがって、RTFをノードセットに変換しようとすると、まっすぐに戻ってきたので、何もしないでください。

(もちろん、XSLT 2.0に移行する以外の)きれいな回避策はありません。私はこのようなコードを構造化することをお勧めします:

<xsl:choose> 
    <xsl:when test="function-available('msxsl:node-set')"> 
     <xsl:apply-templates select="msxsl:node-set($std:colorList)/color" mode="z"/> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:apply-templates select="$std:colorList/color" mode="z"/> 
    </xsl:otherwise> 
</xsl:choose> 

<xsl:template match="color" mode="z"> 
    tr.testid<xsl:value-of select="@testid"/> { 
       color:<xsl:value-of select="."/>; 
      } 
</xsl:template> 
+0

ノードセットにRTFに変換するというか、私はXSLT 1.0 :-)を使用して主張しているユーザーのための私の答えにこれを組み込む予定!。 – Maestro13

+0

Hm pity - 前と同じエラーが出ます - 明らかに、テンプレートに与えられた選択値はノードセットでなければなりません...前と同じトリックでした:$ std:colorListを新しい変数にコピーし、それをテンプレートにフィードします。 – Maestro13

0

ちょうど記録のために、私は以下の最終的な解決策を追加します。これは、テンプレートを適用する前に、RTFのコピーを変数に追加して、Michaelが提案したものとは少し異なります。
xsl解析中にMSXMLがまだエラーが発生しています(明らかに、apply-templatesの選択値をチェックし、ノードセットではなくRTFのときは正しくないと判断します)。属性は、まさにそれを行います。

私には十分
<xsl:choose> 
     <xsl:when test="function-available('msxsl:node-set')"> 
     <xsl:apply-templates select="msxsl:node-set($std:colorList)/color" mode="addTRclassToCSS"/> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:variable name="colorList" select="$std:colorList"/> 
     <xsl:apply-templates select="$colorList" mode="addTRclassToCSS"/> 
    </xsl:otherwise> 
</xsl:choose> 


<xsl:template match="color" mode="addTRclassToCSS"> 
       tr.testid<xsl:value-of select="@testid"/> { 
       color:<xsl:value-of select="."/>; 
       } 
</xsl:template> 
関連する問題