我有以下XML代码:
<root>
<options>
<companies>
<company url="http://www.brown.com">Brown LLC</company>
<company url="http://www.yellow.com">Yellow LLC</company>
<company url="http://www.black.com">Black LLC</company>
<company url="http://www.bourdeaux.com">Bourdeaux LLC</company>
<company url="http://www.orange.com">Orange LLC</company>
</companies>
</options>
</root>
我需要做两件事:
使用公司节点中找到的唯一首字母构建html下拉列表。如:
<select id="colors">
<option value="B">B</option>
<option value="O">O</option>
<option value="Y">Y</option>
</select>
构建辅助下拉列表,其中列出了以特定字母开头的所有公司。如:
<select id="companiesB">
<option value="http://www.black.com">Black LLC</option>
<option value="http://www.bordeaux.com">Bordeaux LLC</option>
<option value="http://www.brown.com">Brown LLC</option>
</select>
任何帮助将不胜感激!
答案 0 :(得分:7)
首先,您需要定义一个键,将所有公司元素“分组”在一起,共享相同的第一个字母
<xsl:key name="companyLetter" match="company" use="substring(text(), 1, 1)" />
接下来,您将遍历所有公司元素
<xsl:for-each select="options/companies/company">
但是,您只想处理公司元素,如果它是第一个字母的第一个元素出现。您可以通过在第一个字母的键中查找第一个元素来查看它是否相同。元素比较使用generate-id()函数
完成<xsl:variable name="firstLetter" select="substring(text(), 1, 1)" />
<xsl:if test="generate-id(.) = generate-id(key('companyLetter', $firstLetter)[1])" >
完全放弃
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:key name="companyLetter" match="company" use="substring(text(), 1, 1)"/>
<xsl:template match="/root">
<select id="colors">
<xsl:for-each select="options/companies/company">
<xsl:sort select="text()"/>
<xsl:variable name="firstLetter" select="substring(text(), 1, 1)"/>
<xsl:if test="generate-id(.) = generate-id(key('companyLetter', $firstLetter)[1])">
<option>
<xsl:attribute name="value">
<xsl:value-of select="$firstLetter"/>
</xsl:attribute>
<xsl:value-of select="$firstLetter"/>
</option>
</xsl:if>
</xsl:for-each>
</select>
</xsl:template>
</xsl:stylesheet>
对于第二个下拉列表,您可以使用以字母作为参数传递的命名模板。您可以使用与上面相同的键查找该字母的所有元素。
<xsl:template name="Companies">
<xsl:param name="firstLetter"/>
<select>
<xsl:attribute name="id">
<xsl:value-of select="$firstLetter"/>
</xsl:attribute>
<xsl:for-each select="key('companyLetter', $firstLetter)">
<xsl:sort select="text()"/>
<option>
<xsl:attribute name="value">
<xsl:value-of select="@url"/>
</xsl:attribute>
<xsl:value-of select="text()"/>
</option>
</xsl:for-each>
</select>
</xsl:template>
要调用模板,只需传递所需参数,例如
<xsl:call-template name="Companies">
<xsl:with-param name="firstLetter">B</xsl:with-param>
</xsl:call-template>
当然,如果您想要显示所有可能的首字母的所有下拉列表,您可以将此设置为for-each循环。
答案 1 :(得分:1)
您应该查看Muenchian Method以获取XSLT中的分组。
答案 2 :(得分:1)
这是两个样式表,第一个用于产生第一个选择:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="k1" match="company" use="substring(., 1, 1)"/>
<xsl:template match="companies">
<select id="colors">
<xsl:apply-templates select="company[generate-id() = generate-id(key('k1', substring(., 1, 1))[1])]">
<xsl:sort select="substring(., 1, 1)" data-type="text"/>
</xsl:apply-templates>
</select>
</xsl:template>
<xsl:template match="company">
<option value="{substring(., 1, 1)}">
<xsl:value-of select="substring(., 1, 1)"/>
</option>
</xsl:template>
</xsl:stylesheet>
第二个用于产生第二个选择元素:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:param name="c" select="'B'"/>
<xsl:output method="html" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="companies">
<select id="companies{$c}">
<xsl:apply-templates select="company[substring(., 1, 1) = $c]">
<xsl:sort select="." data-type="text"/>
</xsl:apply-templates>
</select>
</xsl:template>
<xsl:template match="company">
<option value="{@url}"><xsl:value-of select="."/></option>
</xsl:template>
</xsl:stylesheet>