如何在 XSLT 中应用字母数字排序 [英] How to apply an alphanumeric sort in XSLT

查看:41
本文介绍了如何在 XSLT 中应用字母数字排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基于以下 XML,在 XSL 中实现字母数字排序的最佳方法是什么?

Based on the following XML, what is the best way to achieve an alphanumeric sort in XSL?

编辑:澄清一下,下面的 XML 只是一个简单的示例,真正的 XML 将包含更多变体值.

Edit: to clarify, the XML below is just a simple sample the real XML would contain much more variant values.

<colors>
  <item>
    <label>Yellow 100</label>
  </item>
  <item>
    <label>Blue 12</label>
  </item>
  <item>
    <label>Orange 3</label>
  </item>
  <item>
    <label>Yellow 10</label>
  </item>
  <item>
    <label>Orange 26</label>
  </item>
  <item>
    <label>Blue 117</label>
  </item>
</colors>

例如我希望按此顺序获得最终结果:

E.g. I want a final outcome in this order:

Blue 12, Blue 117, Orange 3, Orange 26, Yellow 10, Yellow 100

这就是我想要的有效".

<xsl:apply-templates select="colors/item">
  <xsl:sort select="label" data-type="text" order="ascending"/><!--1st sort-->
  <xsl:sort select="label" data-type="number" order="ascending"/><!--2nd sort-->
</xsl:apply-templates>   

<xsl:template match="item">
  <xsl:value-of select="label"/>
  <xsl:if test="position() != last()">,</xsl:if>
</xsl:template>

推荐答案

使用 substring-beforesubstring-after 将标签文本拆分为文本和数字部分即可在您的示例中(但是,这不是一般方法,但您明白了):

Splitting the label text into text and number part using substring-before and substring-after will do in your example (however, this is not a general approach, but you get the idea):

<xsl:template match="/">
    <xsl:apply-templates select="colors/item">
      <xsl:sort select="substring-before(label, ' ')" data-type="text" order="ascending"/>
      <!--1st sort-->
      <xsl:sort select="substring-after(label, ' ')" data-type="number" order="ascending"/>
      <!--2nd sort-->
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="item">
    <xsl:value-of select="label"/>
    <xsl:if test="position() != last()">, </xsl:if>
  </xsl:template>

这给出了以下输出:

Blue 12, Blue 117, Orange 3, Orange 26, Yellow 10, Yellow 100

<小时>

更新

解决排序问题的更通用方法是让 xls:sort 元素的 select 属性包含一个可根据排序规则排序的字符串你所期望的.例如.在这个字符串中,所有数字都可以用前导 0 填充,以便按字典顺序将它们排序为 data-type="text" 将导致正确的字母数字顺序.

A more generic way to solve your sorting problem would be to have the select attribute of the xls:sort element contain a string which is sortable according to the sort rules that you expect. E.g. in this string all numbers could be padded with leading 0's so that lexicgraphically sorting them as data-type="text" will result in the correct alphanumeric order.

如果您使用 .NET 的 XSLT 引擎,您可以使用 C# 中的一个简单扩展函数来用前导 0 填充数字:

If you are using the XSLT engine of .NET you could use a simple extension function in C# to pad numbers with leading 0's:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:myExt="urn:myExtension"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                exclude-result-prefixes="msxsl myExt">
  <xsl:output method="xml" indent="yes" />

  <msxsl:script language="C#" implements-prefix="myExt">

    <![CDATA[
        private static string PadMatch(Match match)
        {
            // pad numbers with zeros to a maximum length of the largest int value 
            int maxLength = int.MaxValue.ToString().Length;
            return match.Value.PadLeft(maxLength, '0');
        }

        public string padNumbers(string text)
        {
            return System.Text.RegularExpressions.Regex.Replace(text, "[0-9]+", new System.Text.RegularExpressions.MatchEvaluator(PadMatch));
        }
    ]]>

  </msxsl:script>
  <xsl:template match="/">
    <sorted>
      <xsl:apply-templates select="colors/item">
        <xsl:sort select="myExt:padNumbers(label)" data-type="text" order="ascending"/>
      </xsl:apply-templates>
    </sorted>
  </xsl:template>

  <xsl:template match="item">
    <xsl:value-of select="label"/>
    <xsl:if test="position() != last()">, </xsl:if>
  </xsl:template>

</xsl:stylesheet>

这篇关于如何在 XSLT 中应用字母数字排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆