XSLT 2.0 如何实现字母+数字的自然排序?
实现字母前缀+数字后缀的自然排序
要实现先按字母前缀排序,再按后缀数字从小到大排序的需求,你不需要分两次独立排序,而是在一次<xsl:perform-sort>中添加两个<xsl:sort>节点,分别处理字母部分和数字部分即可。
修改后的代码
<xsl:variable name="sortedPns" as="xs:string*"> <xsl:perform-sort select="distinct-values($combo1/*:pin/*:pkg[$pos]/*:pn/@n)"> <!-- 按字母前缀文本排序 --> <xsl:sort select="replace(., '\d+', '')" data-type="text" order="ascending"/> <!-- 按后缀数字数值排序 --> <xsl:sort select="xs:integer(replace(., '[^\d]+', ''))" data-type="number" order="ascending"/> </xsl:perform-sort> </xsl:variable> <xsl:message select="$sortedPns"/>
代码说明
- 提取字母前缀:
replace(., '\d+', '')会移除字符串中的所有数字字符,只保留开头的字母部分(比如C10会变成C),以此作为第一排序依据,保证同字母的项排在一起。 - 提取数字后缀:
replace(., '[^\d]+', '')会移除字符串中的所有非数字字符,剩下的数字部分转成xs:integer类型,以此作为第二排序依据,确保数字按数值大小而非文本顺序排序(比如8会排在10前面)。 - 一次完成排序:将去重后的原始数据直接传入
<xsl:perform-sort>,通过两层排序规则直接得到目标结果,无需拆分两次排序变量。
运行上述代码后,输入序列B5 C10 C8 D11 D13 D3 D7 D9 E12 E8会被排序为:B5 C8 C10 D3 D7 D9 D11 D13 E8 E12,完全符合需求。
内容的提问来源于stack exchange,提问作者Mark Ainsworth
相关产品推荐
相关产品推荐

