0

タイトルは、実際の問題よりもはるかに複雑に聞こえます。私は、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>

私が得るものはこれです:

PlantType
Tree [= Tree, Flower, Shrub のドロップダウン]
Tree [= Tree, Flower, Shrub のドロップダウン] Tree [= Tree, Flower, Shrub のドロップ
ダウン]

私が欲しいのは:

PlantType
Tree [= Tree, Flower, Shrub (idx 1 事前選択)
のドロップダウン] Flower [= Tree, Flower, Shrub (idx 2 事前選択)
のドロップダウン] Shrub [= Tree, Flower, Shrub (idx 3 事前選択) のドロップダウン]

2 つのアプローチがあると思います。1) 外側のループで listIdx を使用し (一致)、内側のループ内の現在のインデックスを listIdx と比較します。2) 内側のリスト インデックスと外側のリスト インデックスをオンザフライで比較します。主要なコンポーネントを説明するのが十分に簡単であれば、私はそれを非常に感謝しています! ありがとうございました!

4

1 に答える 1

2

あなたができることは、植物要素の現在の位置を保持するためにあなたの外側のループに変数を定義することです

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

次に、内側のループで、この変数に対して2番目の位置を確認できます。この変数は、引き続きスコープ内にあります。

<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:for-eachよりもxsl:apply-templatesを使用する方がよい場合がよくあります。この場合、パラメータとして位置を渡すこともできます。次の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>

また、属性値テンプレートを使用してオプション要素に属性を作成することにも注意してください(静的な名前の要素を作成するためにxsl:elementを使用する必要は実際にはないことに注意してください)。

于 2012-12-10T08:52:05.803 に答える