XSLT 中的排序非常简单。您实际上真正需要知道的是如何对项目进行“分组”。正如 Michael Kay 所评论的,这在 XSLT 2.0 中比在 XSLT 1.0 中容易得多。在 XSLT 1.0 中,您倾向于使用 Muenchian 分组方法,当您第一次看到它时,它会显得令人困惑,但通常是最有效的方法。
从输出的外观来看,您正在进行两次分组。首先,按第一个字母,然后按任一字母组/代码(如果存在),或者title.
Muenchian 分组通过定义一个键来工作,以便快速查找“组”中的所有项目。对于其中的第一个字母组/代码 or title,你可以像这样定义它
<xsl:key name="letter" match="info" use="substring(concat(group/code, title), 1, 1)"/>
(注意:这区分大小写,因此如果您可以混合使用小写和大写起始字母,则可能需要使用“翻译”功能)。
If 组/代码存在,它将使用该的第一个字母,否则它将选取该的第一个字母title.
For the 组/代码 or title本身,关键如下
<xsl:key name="info" match="info" use="title[not(../group)]|group/code"/>
因此,它仅使用不存在“group”元素的“title”元素。
要获得第一个分组的不同首字母,请选择所有info元素并检查它们是否是给定字母的键中的第一个元素。这是这样完成的
<xsl:apply-templates
select="info
[generate-id()
= generate-id(key('letter', substring(concat(group/code, title), 1, 1))[1])]"
mode="letter">
<xsl:sort select="substring(concat(group/code, title), 1, 1)" />
</xsl:apply-templates>
此处使用“模式”是因为最终的 XSLT 必须与模板匹配info.
在匹配模板中,按以下任一分组代码/组 or title然后你可以这样做
<xsl:apply-templates
select="key('letter', $letter)
[generate-id() = generate-id(key('info', title[not(../group)]|group/code)[1])]">
<xsl:sort select="title[not(../group)]|group/code" />
</xsl:apply-templates>
最后,要输出最终组中的所有元素,您只需再次使用该键即可
<xsl:apply-templates select="key('info', $value)[group/code=$value]/title">
这是完整的 XSLT。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="yes"/>
<xsl:key name="letter" match="info" use="substring(concat(group/code, title), 1, 1)"/>
<xsl:key name="info" match="info" use="title[not(../group)]|group/code"/>
<xsl:template match="/*">
<xsl:apply-templates select="info[generate-id() = generate-id(key('letter', substring(concat(group/code, title), 1, 1))[1])]" mode="letter">
<xsl:sort select="substring(concat(group/code, title), 1, 1)" />
</xsl:apply-templates>
</xsl:template>
<xsl:template match="info" mode="letter">
<xsl:variable name="letter" select="substring(concat(group/code, title), 1, 1)" />
<xsl:value-of select="concat($letter, ' ')" />
<xsl:apply-templates select="key('letter', $letter)[generate-id() = generate-id(key('info', title[not(../group)]|group/code)[1])]">
<xsl:sort select="title[not(../group)]|group/code" />
</xsl:apply-templates>
</xsl:template>
<xsl:template match="info">
<xsl:variable name="value" select="title[not(../group)]|group/code" />
<xsl:value-of select="concat($value, ' ')" />
<xsl:apply-templates select="key('info', $value)[group/code=$value]/title">
<xsl:sort select="." />
</xsl:apply-templates>
</xsl:template>
<xsl:template match="title">
<xsl:value-of select="concat(' ', ., ' ')" />
</xsl:template>
</xsl:stylesheet>
当应用于您的 XML 时,输出如下
A
Auto2
Auto3
Auto4
Certificate
Auto5
s
state
Auto
Bill