我有以下xml:
<Users>
<User id="2" name="ABC" Division="HR"/>
<User id="3" name="xyz" Division="Admin"/>
<User id="4" name="LMN" Division="Payroll"/>
<User id="5" name="PQR" Division="IT"/>
</Users>
我想使用XSLT转换它,如下所示:
<Users>
<User id="5" name="PQR" Division="IT"/>
<User id="3" name="xyz" Division="Admin"/>
<User id="2" name="ABC" Division="HR"/>
<User id="4" name="LMN" Division="Payroll"/>
</Users>
我是根据Division属性值来做的,没有具体的规则。 这只是一个样本。 这不是排序,它是一种模板。我可以为用户定义自己的订单并使用xslt进行转换吗?
提前致谢。
答案 0 :(得分:1)
有许多方法可以在XSLT中重新排列节点,从简单的字母或数字排序到复杂的分组。如果您可以将XSLT 2.0或XSLT 1.0与扩展一起使用,则通常可以在模板或循环和函数中使用<xsl:sort>
。如果您受限于XSLT 1.0,您可以在节点集上的模板或循环中进行基本排序,但必须编写更复杂的分组算法(例如:Muenchian方法)。
使用您的简单示例,我想到了一些重新排列节点的方法。使用下面的样式表处理您的示例,您将看到一些示例。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<Results>
<xsl:apply-templates select="Users" mode="sort-name-alphabetical-asc" />
<xsl:apply-templates select="Users" mode="sort-division-alphabetical-desc" />
<xsl:apply-templates select="Users" mode="sort-id-numerical-desc" />
<xsl:apply-templates select="Users" mode="sort-by-number-of-chars-in-division" />
<xsl:apply-templates select="Users" mode="sort-by-last-letter-in-name" />
</Results>
</xsl:template>
<xsl:template match="User">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template match="Users" mode="sort-name-alphabetical-asc">
<example>Sort by name, alphabetical, ascending</example>
<xsl:copy>
<xsl:apply-templates select="User">
<xsl:sort select="@name" data-type="text" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="Users" mode="sort-division-alphabetical-desc">
<example>Sort by Division, alphabetical, descending</example>
<xsl:copy>
<xsl:apply-templates select="User">
<xsl:sort select="@Division" data-type="text" order="descending" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="Users" mode="sort-id-numerical-desc">
<example>Sort by id, numerical, descending</example>
<xsl:copy>
<xsl:apply-templates select="User">
<xsl:sort select="@id" data-type="number" order="descending" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="Users" mode="sort-by-number-of-chars-in-division">
<example>Sort by number of total chars in Division + name</example>
<xsl:copy>
<xsl:apply-templates select="User">
<xsl:sort select="string-length(@Division) + string-length(@name)" data-type="number" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="Users" mode="sort-by-last-letter-in-name">
<example>Sort by last letter in name</example>
<xsl:copy>
<xsl:apply-templates select="User">
<!-- In XSLT 2.0 you can use node()[ends-with(@name, '')] -->
<xsl:sort select="substring(@name, string-length(@name)-1, string-length(@name))" data-type="text" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>