XSLT 分组和循环组

发布于 2024-12-01 10:16:54 字数 3988 浏览 1 评论 0原文

我有以下 XML:

    <DropDownList id="Dropdown">
        <Label text="Dropdown"/>
        <ListItem value="Test1"/>
        <ListItem value="Test2"/>
    </DropDownList>

    <ListBox id="Listbox1" >
        <Label text="SingleSelect"/>
        <ListItem value="Test1"/>
        <ListItem value="Test2"/>
    </ListBox>

然后我有以下列表框的 XSLT:

<xsl:template match="ListBox">
    <th>
        <xsl:apply-templates select="./Label" />
    </th>
    <td>
        <asp:ListBox runat="server" ID="{@id}">
            <Items>
                <xsl:for-each select="./ListItem">
                    <asp:ListItem Value="{@value}">
                        <xsl:attribute name="Text">
                            <!-- fill text accordingly to text attribute or same as value when not specified-->
                            <xsl:choose>
                                <xsl:when test="@text">
                                    <xsl:value-of select="@text"/>
                                </xsl:when>
                                <xsl:otherwise>
                                    <xsl:value-of select="@value"/>
                                </xsl:otherwise>
                            </xsl:choose>
                        </xsl:attribute>

                        <xsl:if test="@selected">
                            <xsl:attribute name="selected">
                                <xsl:value-of select="@selected"/>
                            </xsl:attribute>
                        </xsl:if>
                    </asp:ListItem>
                </xsl:for-each>
            </Items>
        </asp:ListBox>
    </td>
    <td>
        <xsl:apply-templates select="./*[contains(name(), 'Validation')]" />
    </td>
    <xsl:copy-of select="$br"/>
</xsl:template>

使用这种方法,我还必须复制 DropDownList 元素的整个循环。

现在,为了避免大量重复,我知道我可以这样做:

<xsl:template match="ListBox">
    <th>
        <xsl:apply-templates select="./Label" />
    </th>
    <td>
        <asp:ListBox runat="server" ID="{@id}">         
            <Items>
                <xsl:apply-templates select="./ListItem" />
            </Items>
        </asp:ListBox>
    </td>
    <td>
        <xsl:apply-templates select="./*[contains(name(), 'Validation')]" />
    </td>
    <xsl:copy-of select="$br"/>
</xsl:template>


<!-- Helper template for list items -->
<xsl:template match="ListItem">
    <asp:ListItem Value="{@value}">
        <xsl:attribute name="Text">
            <!-- fill text accordingly to text attribute or same as value when not specified-->
            <xsl:choose>
                <xsl:when test="@text">
                    <xsl:value-of select="@text"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="@value"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:attribute>

        <xsl:if test="@selected">
            <xsl:attribute name="selected">
                <xsl:value-of select="@selected"/>
            </xsl:attribute>
        </xsl:if>
    </asp:ListItem>
</xsl:template>

但我不喜欢的是

            <Items>
                <xsl:apply-templates select="./ListItem" />
            </Items>

我必须复制的模式。有没有办法将 {loop through ListItems} 部分完全进入模板并使用 将所有ListItem子节点分组在一起并将它们填充到循环模板中?

I have the following XML:

    <DropDownList id="Dropdown">
        <Label text="Dropdown"/>
        <ListItem value="Test1"/>
        <ListItem value="Test2"/>
    </DropDownList>

    <ListBox id="Listbox1" >
        <Label text="SingleSelect"/>
        <ListItem value="Test1"/>
        <ListItem value="Test2"/>
    </ListBox>

Then I have the following XSLT for the listbox:

<xsl:template match="ListBox">
    <th>
        <xsl:apply-templates select="./Label" />
    </th>
    <td>
        <asp:ListBox runat="server" ID="{@id}">
            <Items>
                <xsl:for-each select="./ListItem">
                    <asp:ListItem Value="{@value}">
                        <xsl:attribute name="Text">
                            <!-- fill text accordingly to text attribute or same as value when not specified-->
                            <xsl:choose>
                                <xsl:when test="@text">
                                    <xsl:value-of select="@text"/>
                                </xsl:when>
                                <xsl:otherwise>
                                    <xsl:value-of select="@value"/>
                                </xsl:otherwise>
                            </xsl:choose>
                        </xsl:attribute>

                        <xsl:if test="@selected">
                            <xsl:attribute name="selected">
                                <xsl:value-of select="@selected"/>
                            </xsl:attribute>
                        </xsl:if>
                    </asp:ListItem>
                </xsl:for-each>
            </Items>
        </asp:ListBox>
    </td>
    <td>
        <xsl:apply-templates select="./*[contains(name(), 'Validation')]" />
    </td>
    <xsl:copy-of select="$br"/>
</xsl:template>

Using this approach, I would have to duplicate the whole looping for the DropDownList element too.

Now, to avoid a lot of the duplication I understand I can do something like this:

<xsl:template match="ListBox">
    <th>
        <xsl:apply-templates select="./Label" />
    </th>
    <td>
        <asp:ListBox runat="server" ID="{@id}">         
            <Items>
                <xsl:apply-templates select="./ListItem" />
            </Items>
        </asp:ListBox>
    </td>
    <td>
        <xsl:apply-templates select="./*[contains(name(), 'Validation')]" />
    </td>
    <xsl:copy-of select="$br"/>
</xsl:template>


<!-- Helper template for list items -->
<xsl:template match="ListItem">
    <asp:ListItem Value="{@value}">
        <xsl:attribute name="Text">
            <!-- fill text accordingly to text attribute or same as value when not specified-->
            <xsl:choose>
                <xsl:when test="@text">
                    <xsl:value-of select="@text"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="@value"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:attribute>

        <xsl:if test="@selected">
            <xsl:attribute name="selected">
                <xsl:value-of select="@selected"/>
            </xsl:attribute>
        </xsl:if>
    </asp:ListItem>
</xsl:template>

But what I don't like about this is the

            <Items>
                <xsl:apply-templates select="./ListItem" />
            </Items>

pattern I would have to duplicate. Is there a way to put the <Items> {loop through ListItems}</Items> part completely into a template and use <xsl:apply-templates select="??" /> to group all ListItem child nodes together and stuff them into the looping template?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

深海夜未眠 2024-12-08 10:16:54

为什么不使用命名模板?

<td>
        <asp:ListBox runat="server" ID="{@id}">
         <xsl:call-template name="LoopItems"/>
        </asp:ListBox>
</td>

使用命名模板:

<xsl:template name="LoopItems">
  <Items>
    <xsl:apply-templates select="ListItem" />
  </Items>
</xsl:template>

Why not using a named template?

<td>
        <asp:ListBox runat="server" ID="{@id}">
         <xsl:call-template name="LoopItems"/>
        </asp:ListBox>
</td>

with named template:

<xsl:template name="LoopItems">
  <Items>
    <xsl:apply-templates select="ListItem" />
  </Items>
</xsl:template>
小耗子 2024-12-08 10:16:54

这个模板怎么样:

<xsl:template match="ListBox|DropDownList">
  <th>
    <xsl:apply-templates select="Label" />
  </th>
  <td>
    <xsl:element name="asp:{name()}">
      <Items>
        <xsl:apply-templates select="ListItem" />
      </Items>
    </xsl:element>
  </td>
  <td>
    <xsl:apply-templates select="*[contains(name(), 'Validation')]" />
  </td>

</xsl:template>

What about this template:

<xsl:template match="ListBox|DropDownList">
  <th>
    <xsl:apply-templates select="Label" />
  </th>
  <td>
    <xsl:element name="asp:{name()}">
      <Items>
        <xsl:apply-templates select="ListItem" />
      </Items>
    </xsl:element>
  </td>
  <td>
    <xsl:apply-templates select="*[contains(name(), 'Validation')]" />
  </td>

</xsl:template>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文