Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在XSLT中应用字母数字排序_Xslt_Sorting_Alphanumeric - Fatal编程技术网

如何在XSLT中应用字母数字排序

如何在XSLT中应用字母数字排序,xslt,sorting,alphanumeric,Xslt,Sorting,Alphanumeric,基于以下XML,在XSL中实现字母数字排序的最佳方法是什么 编辑:澄清一下,下面的XML只是一个简单的示例—真正的XML将包含更多的变量值 这是“有效地”我想要的 <xsl:apply-templates select="colors/item"> <xsl:sort select="label" data-type="text" order="ascending"/><!--1st sort--> <xsl:sort select="label

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

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

这是“有效地”我想要的

<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>

,

在您的示例中,可以使用
前面的子字符串和
后面的子字符串将标签文本拆分为文本和数字部分(不过,这不是一种通用方法,但您可以理解):


更新

解决排序问题的一种更通用的方法是让
xls:sort
元素的
select
属性包含一个字符串,该字符串可以根据您期望的排序规则进行排序。例如,在该字符串中,所有数字都可以用前导0填充,以便按照
data type=“text”
对其进行词汇排序将得到正确的字母数字顺序

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

<?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>

, 

谢谢各位。。。是的,我想我的样本数据有点太笼统了;-)事实上,可能没有任何分隔符和/或数字的位置可能在任何地方。我用更通用的方法更新了我的答案。
<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>
<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
<?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>