2011-07-22 7 views
3

XMLから来るのではなく、XSLに指定された値をループする方法があるのだろうかと思います。XMLではなく、XSLスタイルシートで指定されたハードコードされた値をループする

私は3つのチェックボックスがあり、XMLからの "現在の"値を持っているとします。私は、これは動作しますが、XSLは非常に冗長である

<input id="foo" type="checkbox" name="myvar" value="foo"> 
    <xsl:if test="val='foo'"> 
     <xsl:attribute name="checked">checked</xsl:attribute> 
    </xsl:if> 
</input> <label for="foo">foo</label> 

<input id="bar" type="checkbox" name="myvar" value="bar"> 
    <xsl:if test="val='bar'"> 
     <xsl:attribute name="checked">checked</xsl:attribute> 
    </xsl:if> 
</input> <label for="bar">bar</label> 

<input id="baz" type="checkbox" name="myvar" value="baz"> 
    <xsl:if test="val='baz'"> 
     <xsl:attribute name="checked">checked</xsl:attribute> 
    </xsl:if> 
</input> <label for="baz">baz</label> 

よう

<rootNode> 
    <val>bar</val> 
</rootNode> 

とXSLコードのようなXMLドキュメントを持っていると思います。私はこのような何かを行うことができるようにしたい:私は種類のテンプレートにコードを置くと、複数に<call-template><with-param>呼び出しを使用してこれを取得することができます

<!-- this syntax doesn't work, is there something similar that does? --> 
<xsl:variable name="boxNames" select="'foo','bar','baz'"/> 
<xsl:for-each select="name in $boxNames"> 
    <input id="{$name}" type="checkbox" name="myvar" value="{$name}"> 
     <xsl:if test="val=$name"> 
      <xsl:attribute name="checked">checked</xsl:attribute> 
     </xsl:if> 
    </input> <label for="{$name}"><xsl:value-of select="$name"/></label> 
</xsl:for-each> 

が、それはだ上で多くのスペースを節約しません。元の。

XSLでこれを行うための簡潔な方法はありますか?私は間違いなく、すべてのチェックボックス名をXML出力に入れることはできません。大きなリストであり、XMLを不必要に膨らませます。

答えて

3

はい、document('')関数を呼び出すことでXSLのソース(!)を取得できます。この関数をノードデータソースとして使用できます。

<xsl:template name="boxNames"> <!-- not used as template --> 
    <name>foo</name> 
    <name>bar</name> 
    <name>baz</name> 
</xsl:template> 

[...]

<xsl:variable name="boxNames" select="document('')/xsl:stylesheet/xsl:template[@name='boxNames']/name" /> 
+1

未使用のテンプレートにデータを入れるのではなく、XSLT名前空間以外の名前空間を使用する場合は、最上位の要素として配置できます。 XSLTプロセッサは、そのようなトップレベルの要素を無視します。 –

+0

パーフェクト、これはまさに私が望んでいたものです!私はJukkaに同意します。別の名前空間を使用して実際にテンプレートではないことを強調します。 –

0

テンプレートマッチは、各ループに対して効果的です。

<xsl:template match="/"> 
    <xsl:apply-templates match="namespace:ItemName"/> 
</xsl:template> 

<xsl:template match="namespace:ItemName"> 
    <input> 
     <xsl:attribute name="id"><xsl:value-of select="."></xsl:attribute> 
     <xsl:attribute name="type">checkbox</xsl:attribute> 
     <xsl:attribute name="name">myvar</xsl:attribute> 
     <xsl:attribute name="value"><xsl:value-of select="."></xsl:attribute> 
     <xsl:value-of select="."> 
    </input> 
    <label> 
     <xsl:attribute name="for"><xsl:value-of select="." /></xsl:attribute> 
     <xsl:value-of select="."/> 
    </label> 
</xsl:template> 

これはそれを減らすはずです。

+0

しかし、それは可能なすべての値、XMLから 'namespace:ItemName'を引っ張っていますか?私は具体的には、すべてのXML出力にすべての可能な値を含めることは望ましくなく、 "現在の"値だけがXMLに含まれています。 –

3

あなたが提案したコードに非常に近いある、これを試してみてください:

<xsl:variable name="boxNames" select="'foo','bar','baz'"/> 
<xsl:variable name="val" select="val"/> 
<xsl:for-each select="$boxNames"> 
    <input id="{.}" type="checkbox" name="myvar" value="{.}"> 
     <xsl:if test="$val=."> 
      <xsl:attribute name="checked">checked</xsl:attribute> 
     </xsl:if> 
    </input> <label for="{.}"><xsl:value-of select="."/></label> 
</xsl:for-each> 

それはしかしXSLT 2.0プロセッサを必要とします。

+0

私はXSLT 2.0が私の夢を実現すると思いました。 :)残念ながら私はXSLT 1.0をサポートしなければなりません。しかし、まだ知って良い、ありがとう! –

関連する問題