XSLT - 重新排序逗号分隔的字符串

时间:2012-08-30 11:12:51

标签: xml xslt sorting xslt-2.0

我希望有人能够提供帮助。我有逗号分隔的字符串,例如A10,A12,A11,S10,S11,S12这需要重新排序到S10,A10,S11,A11,S12,A12

订购标准如下,

对于输入XML:

<root>
    <row>A10,A12,A11,S10,S11,S12</row>
</root>

期望的输出:

<root>
    <row>S10,A10,S11,A11,S12,A12</row>
</root>

2 个答案:

答案 0 :(得分:3)

在2.0中:

<xsl:perform-sort select="tokenize(row, ',')">
  <xsl:sort select="xs:integer(substring(., 2))"/>
  <xsl:sort select="substring(., 1, 1)" order="descending"/>
</xsl:perform-sort>

答案 1 :(得分:1)

请注意

这个问题的要求并没有涵盖某些可能的输入,因此,Michael Kay和这个解决方案的两个当前解决方案可以产生不同的结果。

前者产生的结果总是按数字排序(可能违反交替的SA要求。

此解决方案会生成SA始终按此顺序交替的结果,但可能并不总是满足数字排序要求。

<强>示例1

A8,A10,A12,A11,S9,S10,S11,S12

Michael Kay的解决方案

A8,S9,S10,A10,S11,A11,S12,A12

此处“S始终在A(交替)之前”的要求未得到满足

当前解决方案产生

S9,A8,S10,A10,S11,A11,S12,A12

这里满足了交替要求,但数字排序要求不是。


此转化

<xsl:stylesheet version="2.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:variable name="vTokens" select="tokenize(/*/row, ',')"/>

    <xsl:variable name="vASeq" as="xs:string*">
     <xsl:perform-sort select="$vTokens[starts-with(.,'A')]">
      <xsl:sort select="substring(.,2)" data-type="number"/>
     </xsl:perform-sort>
    </xsl:variable>

    <xsl:variable name="vSSeq" as="xs:string*">
     <xsl:perform-sort select="$vTokens[starts-with(.,'S')]">
      <xsl:sort select="substring(.,2)" data-type="number"/>
     </xsl:perform-sort>
    </xsl:variable>

 <xsl:template match="/">
     <root>
      <row>
        <xsl:sequence select=
        "string-join(
                     (for $i in 1 to count($vSSeq)
                        return
                          ($vSSeq[$i], $vASeq[$i])
                      ),
                      ','
                           )
        "/>
      </row>
     </root>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档

<root>
    <row>A10,A12,A11,S10,S11,S12</row>
</root>

会产生想要的正确结果:

<root>
   <row>S10,A10,S11,A11,S12,A12</row>
</root>