XSLT <xsl:sort> 元素最全详解(2025 年真实用法 + 所有坑一次踩完)
<xsl:sort> 是 XSLT 中唯一负责排序的指令,必须放在 <xsl:for-each> 或 <xsl:apply-templates> 的最前面。
一、基本语法(就这两种位置)
<!-- 用法1:放在 for-each 里(最常见) -->
<xsl:for-each select="book">
<xsl:sort select="price" order="descending" data-type="number"/>
<xsl:sort select="title" lang="zh-CN"/> <!-- 多重排序 -->
...
</xsl:for-each>
<!-- 用法2:放在 apply-templates 里(更优雅) -->
<xsl:apply-templates select="book">
<xsl:sort select="price" order="descending"/>
<xsl:sort select="publish-date" data-type="text" order="ascending"/>
</xsl:apply-templates>
二、完整属性表(2025 年全版本通杀)
| 属性 | 说明 | 常用值举例 |
|---|---|---|
select | 必须,要排序的字段(XPath 表达式) | select="price"、select="@id"、select="translate(title,'《》','')" |
order | 升序还是降序 | ascending(默认)、descending |
data-type | 按文本还是数字排序(超容易忘!) | text(默认)、number |
lang | 语言排序规则(中文、拼音) | zh-CN、en、ja |
case-order | 大小写优先 | upper-first、lower-first |
collation | 自定义排序规则(拼音、笔画、日期等) | http://www.w3.org/2005/xpath-functions/collation/html5 |
三、2025 年最常用的 10 种真实排序写法(直接复制)
<!-- 1. 最常见:价格从高到低(必须加 data-type="number"!) -->
<xsl:sort select="price" data-type="number" order="descending"/>
<!-- 2. 书名按中文拼音排序(2025 年标配) -->
<xsl:sort select="title" lang="zh-CN"/>
<!-- 3. 多重排序:先按作者拼音 → 再按出版年份倒序 -->
<xsl:sort select="author" lang="zh-CN"/>
<xsl:sort select="year" data-type="number" order="descending"/>
<!-- 4. 日期倒序(新书在前) -->
<xsl:sort select="publish-date" data-type="text" order="descending"/>
<!-- 推荐格式:2025-03-01 这样按文本倒序就是时间倒序 -->
<!-- 5. 销量排序(字符串带“万”字) -->
<xsl:sort select="number(translate(sales, '万人', ''))" data-type="number" order="descending"/>
<!-- 6. 按书名字数排序(脑洞用法) -->
<xsl:sort select="string-length(title)" data-type="number"/>
<!-- 7. 忽略《》书名号后排序 -->
<xsl:sort select="translate(title, '《》', '')" lang="zh-CN"/>
<!-- 8. 拼音排序(Saxon 专属超强写法) -->
<xsl:sort select="title" collation="http://saxon.sf.net/collation?lang=zh-CN"/>
<!-- 9. 章节目录按 @order 属性排序 -->
<xsl:apply-templates select="chapter">
<xsl:sort select="@order" data-type="number"/>
</xsl:apply-templates>
<!-- 10. 随机排序(每次刷新都不一样) -->
<xsl:for-each select="book">
<xsl:sort select="generate-id()"/> <!-- 经典技巧 -->
</xsl:for-each>
四、2025 年必知 3 大坑(99% 的人都踩过)
| 场景 | 错误写法 | 正确写法 | 说明 |
|---|---|---|---|
| 价格排序变成字典序 | <xsl:sort select="price"/> | <xsl:sort select="price" data-type="number"/> | 忘了加 data-type=”number” → 9 在 100 前面 |
| 中文排序乱了 | <xsl:sort select="title"/> | <xsl:sort select="title" lang="zh-CN"/> | 必须加 lang=”zh-CN” |
| 多重排序顺序反了 | 先写 title 再写 price | 写在前面的优先级更高! | 排序顺序 = 代码顺序 |
五、与 <xsl:for-each-group> 完美配合(2025 标配)
<!-- 先按作者分组 → 每组内再按价格倒序 -->
<xsl:for-each-group select="book" group-by="author">
<h2><xsl:value-of select="current-grouping-key()"/></h2>
<ul>
<xsl:for-each select="current-group()">
<xsl:sort select="price" data-type="number" order="descending"/>
<li><xsl:value-of select="title"/> ¥<xsl:value-of select="price"/></li>
</xsl:for-each>
</ul>
</xsl:for-each-group>
六、30 秒实战挑战(来真的)
把这个 XML 按销量从高到低排序(销量是“12.5万册”这种格式):
<books>
<book><title>三体</title><sales>85.3万册</sales></book>
<book><title>活着</title><sales>120万册</sales></book>
<book><title>围城</title><sales>45万册</sales></book>
</books>
答案(一行搞定):
<xsl:for-each select="books/book">
<xsl:sort select="number(translate(sales, '万册', ''))"
data-type="number" order="descending"/>
<xsl:value-of select="title"/>(<xsl:value-of select="sales"/>)<br/>
</xsl:for-each>
输出:
活着(120万册)
三体(85.3万册)
围城(45万册)
七、一句话总结
排序只有两件事:① select 写对字段 ② data-type 别忘!
其余全是细节,记住上面 10 种写法,你就能在任何项目里优雅地排任何序。
需要我现在帮你写任何排序(拼音、价格、日期、销量、章节号、随机、去《》后排序……)?
直接把 XML 和排序需求甩过来,10 秒出成品!