Циклы по жестко запрограммированным значениям указываются в таблице стилей XSL, а не в XML - PullRequest
3 голосов
/ 22 июля 2011

Мне интересно, есть ли способ зацикливания значений , указанных в XSL , вместо того, чтобы исходить из XML.

Допустим, у меня есть 3 возможных флажка с«текущее» значение, которое приходит из XML.Я хотел бы иметь XML-документ, такой как

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

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

. Это работает, но XSL очень многословен.Я хотел бы иметь возможность сделать что-то вроде этого:

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

Я могу получить это, поместив код в шаблон и используя несколько вызовов <call-template> <with-param>, но это не такt сэкономить много места по сравнению с оригиналом.

Есть ли какой-нибудь краткий способ сделать это с помощью XSL?Я определенно не могу поместить все имена флажков в выводе XML, это большой список и излишне раздувает XML.

Ответы [ 3 ]

3 голосов
/ 22 июля 2011

Да, вы можете получить источник (!) XSL, вызвав функцию document(''), которую затем сможете использовать в качестве источника данных узла.

<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" />
3 голосов
/ 22 июля 2011

Попробуйте это, что очень близко к предложенному вами коду:

<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 голосов
/ 22 июля 2011

Шаблонные совпадения эффективны для каждого цикла.

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

Это должно сократить его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...