1

xsl:choose(MSXML エンジンで使用するために) を使用して rtf からノード セット変数を作成することは可能ですか?

私は次の構造を持っています:

<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>

しかし、これは正しく機能しません。MSXMLcolorListはノード セットではないというエラーを出すため、xsl:for-each.

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

実際の例では、変数に「コピー」std:colorListしたため、このエラーは発生しなかったことに注意してください。colorListどうやらこれは実行時エラーではなく、xsl 解析エラーです。
以外のものを使用する必要がありxsl:copy-ofますか? または、同じことを達成する別の方法はありますか?

ご参考までに、std:colorList内容は次のとおりです。

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

2 に答える 2

3

残念ながら、XSLT 1.0 では、xsl:variable に 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>
于 2012-03-23T17:18:46.120 に答える
0

念のため、以下に最終的な解決策を追加します。これは Michael が提案したものとは少し異なり、テンプレートを適用する前に RTF のコピーを変数に追加します。
そうしないと、MSXML は xsl 解析中にエラーが発生するためです (明らかに、apply-templates の select 値をチェックし、それがノード セットではなく RTF である場合は正しくないと結論付けます。また、Michael が言ったように、xsl:variable select 属性はそうします)それだけです: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>
于 2012-03-23T17:52:55.560 に答える