xsl排序不按预期工作

时间:2014-12-29 09:01:50

标签: sorting xslt

我有以下XML并使用XSLT2.0

 <A>
            <BID>Pt.IV</BID>
            <BID>Pt.III</BID>
            <BID>Pt.IIIA</BID>
            <BID>Pt.IIIB</BID>
            <BID>Pt.IIIC</BID>
            <BID>Pt.IIID</BID>
            <BID>Pt.IIIE</BID>
            <BID>Pt.IIIF</BID>
            <BID>Pt.IIIAA</BID>
            <BID>s.2(1)</BID>
            <BID>s.3</BID>
            <BID>s.3(1)</BID>
            <BID>s.3(2)</BID>
            <BID>s.3A</BID>
            <BID>s.3B</BID>
            <BID>s.4</BID>
            <BID>s.4(2)</BID>
            <BID>s.4(5)</BID>
            <BID>s.4(2A)</BID>
            <BID>s.4(4A)</BID>
            <BID>s.6(3)</BID>
            <BID>s.7</BID>
            <BID>s.7A</BID>
            <BID>s.8</BID>
            <BID>s.9</BID>
            <BID>s.12</BID>
            <BID>s.13</BID>
            <BID>s.20A</BID>
            <BID>s.20F</BID>
            <BID>s.20O</BID>
            <BID>s.20S</BID>
            <BID>s.20T</BID>
            <BID>s.20W</BID>
            <BID>s.21</BID>
            <BID>s.21(2)</BID>
            <BID>s.21(3)</BID>
            <BID>s.21(2A)</BID>
            <BID>s.21(4B)</BID>
            <BID>s.21(4C)</BID>
            <BID>s.21(4D)</BID>
            <BID>s.21B</BID>
            <BID>s.22(1)</BID>
            <BID>s.22(1)(b)</BID>
            <BID>s.22(4)</BID>
            <BID>s.23</BID>
            <BID>s.25(1A)</BID>
            <BID>s.27</BID>
            <BID>s.28</BID>
            <BID>s.31</BID>
            <BID>s.20O(2)</BID>
            <BID>s.20W(2)</BID>
            <BID>s.21B(1)</BID>
            <BID>s.21B(2)</BID>
            <BID>s.21B(3)</BID>
        </A>

这里我试图使用下面的XSLT对BID的值进行排序。

 <xsl:template match="A">
    <xsl:for-each select="BID">
<xsl:sort select="substring-after(.,'.')"/>
<table class="toa-entry">
                            <tbody>
<tr class="secondary-entry">
<td class="entry-name">
<xsl:value-of select="."/></td>
                                    </tr>

</tbody>
</table>
</xsl:for-each>
</xsl:template>

此处获取的输出如下所示。

enter image description here

但预期如下。

s2(1)
s3
s3(1)
s3(2) 
s3A 
s3B 
s4 
s4(2) 
s4(5) 
s4(2A) 
s4(4A) 
s6(3) 
s7 
s7A 
s8 
s9 
s12 
s13 
s20A 
s20F 
s20O 
s20O(2) 
s20S 
s20T 
s20W 
s20W(2) 
s21 
s21(2) 
s21(3) 
s21(2A) 

这里发生了什么,排序正在首先使所有数字从1开始,然后是2,依此类推。

我希望它按常规升序排列。 1,2,2a,3,3a等。

请告诉我如何获得此输出。

这是工作演示。

DEMO

由于

3 个答案:

答案 0 :(得分:3)

你应该尝试类似的东西:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/A">
    <table >
        <xsl:for-each select="BID">
            <xsl:sort select="substring-before(., '.')" data-type="text" order="ascending"/>
            <xsl:sort select="replace(substring-before(substring-after(concat(., '('), '.'), '('),'[A-Z]', '')" data-type="number" order="ascending"/>
            <xsl:sort select="replace(substring-before(substring-after(concat(., '('), '.'), '('),'[0-9]', '')" data-type="text" order="ascending"/>
            <xsl:sort select="substring-after(., '(')" data-type="text" order="ascending"/>
            <tr>
                <td><xsl:value-of select="."/></td>
            </tr>
        </xsl:for-each>
    </table>
</xsl:template>

</xsl:stylesheet>

(已呈现)结果,应用于您的示例时:

Pt.III
Pt.IIIA
Pt.IIIAA
Pt.IIIB
Pt.IIIC
Pt.IIID
Pt.IIIE
Pt.IIIF
Pt.IV
s.2(1)
s.3
s.3(1)
s.3(2)
s.3A
s.3B
s.4
s.4(2)
s.4(2A)
s.4(4A)
s.4(5)
s.6(3)
s.7
s.7A
s.8
s.9
s.12
s.13
s.20A
s.20F
s.20O
s.20O(2)
s.20S
s.20T
s.20W
s.20W(2)
s.21
s.21(2)
s.21(2A)
s.21(3)
s.21(4B)
s.21(4C)
s.21(4D)
s.21B
s.21B(1)
s.21B(2)
s.21B(3)
s.22(1)
s.22(1)(b)
s.22(4)
s.23
s.25(1A)
s.27
s.28
s.31

答案 1 :(得分:1)

您无法对数字数据使用文本排序算法。

即使您删除了字符,您的数据值仍然是文本值。

如果需要数字排序,则需要告诉解析器数据的数据类型,您可以使用data-type attribute来完成。

  

数据类型文本|号码| qname

     

可选。指定要排序的数据的数据类型。默认为&#34;文字&#34;

编辑:将此正则表达式替换为:[^a-zA-Z0-9 -]

这里有一个限制因为正则表达式从值中删除了所有非数字字符。因此,如果初始列表尚未在数字因子内正确排序,例如

  • 。21(4B)
  • 。21(4C)
  • 。21(4D)

然后排序将忽略值的字母组成部分。

答案 2 :(得分:1)

如果您正在使用Saxon,则可以请求将排序键中的任何数字序列视为数字,然后s12在s9之后排序。

collation="http://saxon.sf.net/collation?alphanumeric=yes"

它不会处理罗马数字:排序&#34; App IX&#34;在&#34; App VIII&#34;仍然是一个挑战!