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>
开发者_Python百科 <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?
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>
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>
精彩评论