【问题标题】:set selected attribute of html option element within select based on outer for-each index根据外部 for-each 索引在 select 中设置 html option 元素的选定属性
【发布时间】:2012-12-10 04:07:30
【问题描述】:

标题听起来比实际问题要复杂得多:我一直在尝试通过在 stackoverflow 和其他地方找到的点点滴滴把事情放在一起,但我不太明白。

任务:我有一个项目列表,我想遍历它,对于每次迭代,我想创建一个下拉列表,然后默认情况下根据当前整体索引选择项目。

这个例子会很清楚。 这是 XML:

<?xml version="1.0" encoding="UTF-8"?>
<Plants>
   <Plant PlantId="13" PlantType="Tree"/>
   <Plant PlantId="25" PlantType="Flower"/>
   <Plant PlantId="70" PlantType="Shrub"/>
</Plants>

然后我有一些 XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html" indent="yes" encoding="UTF-8" omit-xml-declaration="yes"/>
    <xsl:template match="/">
        <xsl:param name="listIdx" select="0">
        </xsl:param>
        <table>
            <thead>
                    <tr>
                        <td>PlantType</td>
                    </tr>
            </thead>
            <tbody>
                <xsl:for-each select="Plants/Plant">
                    <tr>
                        <td>
                            <select>
                                <xsl:for-each select="/Plants/Plant">
                                    <xsl:element name="option">
                                        <xsl:attribute name="value">
                                            <xsl:value-of select="@PlantId"/>
                                        </xsl:attribute>
                                        <xsl:if test="count(.) = 2">
                                            <xsl:attribute name="selected">selected</xsl:attribute>    
                                        </xsl:if>
                                        <xsl:value-of select="@PlantType"/>
                                    </xsl:element>
                                </xsl:for-each>
                            </select>
                        </td>
                    </tr>
                </xsl:for-each>
            </tbody>
        </table>        
    </xsl:template>
</xsl:stylesheet>

我得到的是这样的:

植物类型
树 [=带有树、花、灌木的下拉菜单]
树 [=带有树、花、灌木的下拉菜单]
树 [=带有树、花、灌木的下拉菜单]

我想要的是:

植物类型
树 [=带有树、花、灌木的下拉菜单(预选 idx 1)]
花 [=带有树、花、灌木的下拉菜单(idx 2 预选)]
灌木 [=带有树、花、灌木的下拉菜单(idx 3 预选)]

我想会有两种方法:1)在外循环中使用listIdx(匹配),然后将内循环中的当前索引与listIdx进行比较。 2)动态比较内部列表索引和外部列表索引。如果说明关键组件很容易,我将非常感激!谢谢!

【问题讨论】:

  • 您提供的当前和想要的输出不能由提供的转换产生。请编辑问题并纠正这个矛盾。特别是提供确切想要的转换结果——不是对它的口头描述,也不是浏览器如何显示它。另外,请注意&lt;xsl:if test="count(.) = 2"&gt; 中的测试条件始终为false(),因为单个节点(.)的计数始终为 1。

标签: xslt select foreach option value-of


【解决方案1】:

你可以做的是在你的外部循环中定义一个变量来保存植物元素的当前位置

 <xsl:variable name="position" select="position()"/>

然后,在你的内部循环中,你可以检查这个变量的第二个位置,它仍然在范围内

<xsl:if test="position() = $position">
    <xsl:attribute name="selected">selected</xsl:attribute>
</xsl:if>

这是本例中的完整 XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html" indent="yes" encoding="UTF-8" omit-xml-declaration="yes"/>

    <xsl:template match="/">
        <xsl:param name="listIdx" select="0"/>
        <table>
            <thead>
                <tr>
                    <td>PlantType</td>
                </tr>
            </thead>
            <tbody>
                <xsl:for-each select="Plants/Plant">
                    <xsl:variable name="position" select="position()"/>
                    <tr>
                        <td>
                            <select>
                                <xsl:for-each select="/Plants/Plant">
                                    <xsl:element name="option">
                                        <xsl:attribute name="value">
                                            <xsl:value-of select="@PlantId"/>
                                        </xsl:attribute>
                                        <xsl:if test="position() = $position">
                                            <xsl:attribute name="selected">selected</xsl:attribute>
                                        </xsl:if>
                                        <xsl:value-of select="@PlantType"/>
                                    </xsl:element>
                                </xsl:for-each>
                            </select>
                        </td>
                    </tr>
                </xsl:for-each>
            </tbody>
        </table>
    </xsl:template>
</xsl:stylesheet>

这会产生以下输出

<table>
    <thead>
        <tr>
            <td>PlantType</td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <select>
                    <option value="13" selected="selected">Tree</option>
                    <option value="25">Flower</option>
                    <option value="70">Shrub</option>
                </select>
            </td>
        </tr>
        <tr>
            <td>
                <select>
                    <option value="13">Tree</option>
                    <option value="25" selected="selected">Flower</option>
                    <option value="70">Shrub</option>
                </select>
            </td>
        </tr>
        <tr>
            <td>
                <select>
                    <option value="13">Tree</option>
                    <option value="25">Flower</option>
                    <option value="70" selected="selected">Shrub</option>
                </select>
            </td>
        </tr>
    </tbody>
</table>

然而,使用 xsl:apply-templates 而不是 xsl:for-each 通常更好,如果只是为了避免过多的缩进。在这种情况下,您也可以将位置作为参数传递。以下 XSLT 也产生相同的输出

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html" indent="yes" encoding="UTF-8" omit-xml-declaration="yes"/>

    <xsl:template match="/">
        <xsl:param name="listIdx" select="0"/>
        <table>
            <thead>
                <tr>
                    <td>PlantType</td>
                </tr>
            </thead>
            <tbody>
                <xsl:apply-templates select="Plants/Plant"/>
            </tbody>
        </table>
    </xsl:template>

    <xsl:template match="Plant">
        <tr>
            <td>
                <select>
                    <xsl:apply-templates select="/Plants/Plant" mode="options">
                        <xsl:with-param name="position" select="position()"/>
                    </xsl:apply-templates>
                </select>
            </td>
        </tr>
    </xsl:template>

    <xsl:template match="Plant" mode="options">
        <xsl:param name="position"/>
        <option value="{@PlantId}">
            <xsl:if test="position() = $position">
                <xsl:attribute name="selected">selected</xsl:attribute>
            </xsl:if>
            <xsl:value-of select="@PlantType"/>
        </option>
    </xsl:template>
</xsl:stylesheet>

还要注意使用属性值模板在 option 元素上创建 value 属性(并注意没有真正需要使用 xsl:element 创建静态名称元素)

【讨论】:

    猜你喜欢
    • 2016-03-23
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 2011-08-11
    • 2021-07-26
    • 2020-02-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多