2013-01-10 16 views
6

小さな問題が残っています。XSLT変数を動的名で参照する

XSL-ファイル:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:fn="http://www.w3.org/2005/xpath-functions"> 
<xsl:template match="/"> 


<xsl:variable name="unumericValue" select="10" /> 
<xsl:variable name="uanotherValue" select="8" /> 



<xsl:for-each select="/root/try"> 
<xsl:value-of select="var" /> 
<xsl:variable name="min"><xsl:value-of select="@minimum" /></xsl:variable> 
<xsl:value-of select="@type" /> 
<xsl:variable name="referenceName"><xsl:value-of select='concat("u",var)' /></xsl:variable> 
<xsl:value-of select="$referenceName" /> 
<xsl:if test='$referenceName > $min'> 
<p>Do something.</p> 
</xsl:if> 
</xsl:for-each> 

</xsl:template> 
</xsl:stylesheet> 

XMLファイル:

<?xml version="1.0" encoding="UTF-8"?> 
<?xml-stylesheet type="text/xsl" href="q1.xsl"?> 
<root> 
<try type="compare" minimum="9"> 
<var>numericValue</var> 
<something>...</something> 
</try> 

<try type="compare" minimum="10"> 
<var>anotherValue</var> 
<something>...</something> 
</try> 
</root> 

あなたはXMLファイルは、XSLTファイル内の変数に一致する必要があります2 VAR-要素を持って見ることができるように。しかし、どの構文が正しいかわからない。 $ referenceNameは、使用したい変数の名前です。しかし、名前を既存の変数に参照する方法はわかりません。

答えて

11

$referenceNameは、「unumericValue」という名前の変数への参照ではありません。それはちょうど文字列値 "unumericValue"などであるので、$minより大きくなることはありません。しかし、少し余分な作業で、その名前で変数を見つけるためのトリックがある。ここで注意すべき

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:variable name="numericValue" select="10" /> 
    <xsl:variable name="anotherValue" select="8" /> 
    <xsl:variable name="vars" select="document('')/*/xsl:variable" /> 

    <xsl:template match="/"> 
    <xsl:variable name="referenceName" select="'numericValue'" /> 
    <xsl:variable name="referenceValue" select="$vars[@name = $referenceName]/@select" /> 
    Reference value: <xsl:value-of select="$referenceValue" /> 
    </xsl:template> 
</xsl:stylesheet> 

一つの大きな制限は、これが唯一の一定の数値である変数のために働くだろうということです。

ここでは定数文字列値を持つ変数をシミュレートする方法です:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:v="variables-node" 
> 
    <v:variables> 
    <v:variable n="numericValue" value="10" /> 
    <v:variable n="nonNumericValue" value="Hello World" /> 
    </v:variables> 
    <xsl:variable name="vars" select="document('')//v:variables/v:variable" /> 

    <xsl:template match="/"> 
     <xsl:variable name="referenceName" select="'nonNumericValue'" /> 
     <xsl:variable name="referenceValue" select="$vars[@n = $referenceName]/@value" /> 
     <xsl:value-of select="concat('The variable with the name ', $referenceName, ' has the value ', $referenceValue)"/> 
    </xsl:template> 
</xsl:stylesheet> 

そして最後に、計算値と変数をシミュレートする方法:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:exslt="http://exslt.org/common" 
> 

    <xsl:variable name="varsRaw"> 
    <var n="computedValue" value="{concat('2 + 4 is ', 2 + 4)}" /> 
    <var n="computedNumber" value="{22 div 7}" /> 
    </xsl:variable> 
    <xsl:variable name="vars" select="exslt:node-set($varsRaw)/var" /> 

    <xsl:template match="/"> 
     <xsl:variable name="referenceName" select="'computedValue'" /> 
     <xsl:variable name="referenceValue" select="$vars[@n = $referenceName]/@value" /> 
     <xsl:value-of select="concat('The variable with the name ', $referenceName, ' has the value ', $referenceValue)"/> 

     <xsl:value-of select="'  '"/> 

     <xsl:variable name="referenceName2" select="'computedNumber'" /> 
     <xsl:variable name="referenceValue2" select="$vars[@n = $referenceName2]/@value" /> 
     <xsl:value-of select="concat('The variable with the name ', $referenceName2, ' has the value ', $referenceValue2)"/> 
    </xsl:template> 
</xsl:stylesheet> 

最後のアプローチは、実際には、おそらく最もオーソドックスですしかし、XSLTプロセッサに依存する(少なくともXSLT 1.0では)node-set()関数が必要です。

+0

ありがとうございました。最初の提案は私にとって素晴らしい仕事でした。 – eadrax

1

ほとんどのプログラミング言語と同様に、XSLT変数名は実行時にアクセスできません。実行時に変数が存在しない場合もあります。オプティマイザは、変数が使用されている時点で変数への参照をすべてインライン展開するなど、あらゆる種類のトリックを実行できます。

最高のアプローチは、標準の名前で変数を持ち、それにXMLコンテンツを与えることです。 XMLの要素名と属性名は、変数名とは異なり、実行時にアクセス可能です。ところで

5

、これをしない:

<xsl:variable name="min"><xsl:value-of select="@minimum" /></xsl:variable> 

あなたはこれを行うことができるとき:

<xsl:variable name="min" select="@minimum" /> 

それだけ冗長、それはまた、非効率的だていない - データをコピーする必要はありません既存のノードへの参照だけが必要な場合は、非常に高価な操作である新しいツリーを構築します。

+0

もちろん、あなたは正しいです。また、書くのがずっと簡単で短くて済んでいます:) – eadrax

関連する問題