我有以下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>
此处获取的输出如下所示。
但预期如下。
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等。
请告诉我如何获得此输出。
这是工作演示。
由于
答案 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 -]
这里有一个限制因为正则表达式从值中删除了所有非数字字符。因此,如果初始列表尚未在数字因子内正确排序,例如
然后排序将忽略值的字母组成部分。
答案 2 :(得分:1)
如果您正在使用Saxon,则可以请求将排序键中的任何数字序列视为数字,然后s12在s9之后排序。
collation="http://saxon.sf.net/collation?alphanumeric=yes"
它不会处理罗马数字:排序&#34; App IX&#34;在&#34; App VIII&#34;仍然是一个挑战!