有没有一种内置的或简单的方法来生成按字母顺序排序的值序列?
例如,下面的item元素有一个用于排序的子sequence元素。数据是为另一个需要此信息的系统生成的,因为它不适用于文档排序。
<list>
<item>
<sequence>1</sequence>
</item>
<item>
<sequence>2</sequence>
</item>
<item>
<sequence>3</sequence>
</item>
<item>
<sequence>4</sequence>
</item>
...
<item>
<sequence>14</sequence>
</item>
<item>
<sequence>15</sequence>
</item>系统不按数字排序,而是按字母顺序排序,并且无法更改此行为。因此,项目被排序为1,10,11,12,13,14,15,2,3,4,5,6,7,8,9
此外,项目的实际数量是无限的,因此需要有一种通用的方法来生成按正确顺序排序的字母序列。也就是说,项目的数量应该相对较少,在1000项以下。
这就是我到目前为止所知道的:
<xsl:variable name="idchars" as="xs:string *"
select="
('0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F','G','H','I','J','K','L','M',
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
'a','b','c','d','e','f','g','h','i','j','k','l','m',
'n','o','p','q','r','s','t','u','v','w','x','y','z')
"
/>
<xsl:variable name="idlen" as="xs:integer" select="count($idchars)" />
<xsl:function name="f:genId" as="xs:string">
<xsl:param name="pSeq" as="xs:integer" />
<xsl:variable name="vLen" as="xs:integer" select="$pSeq idiv $idlen" />
<xsl:value-of>
<xsl:for-each select="1 to $vLen">
<xsl:sequence select="$idchars[$idlen]" />
</xsl:for-each>
<xsl:sequence select="$idchars[$pSeq mod $idlen]" />
</xsl:value-of>
</xsl:function>发布于 2020-12-22 03:42:49
您可以使用format-number()来生成具有可变长度前导零的左填充数字序列,然后使用codepoints-to-string()将这些数字转换为字母,然后使用string-join()将它们连接在一起
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:f="local">
<xsl:output indent="yes"/>
<xsl:function name="f:genId" as="xs:string">
<xsl:param name="pSeq" as="xs:integer" />
<xsl:param name="digits" as="xs:integer"/>
<xsl:variable name="picture" select="string-join( ((1 to $digits) ! '0'), '')" />
<xsl:variable name="padded-string" select="format-number($pSeq, $picture)" as="xs:string"/>
<xsl:variable name="padded-letter-seq" select="(1 to string-length($picture)) ! substring($padded-string, ., 1) ! codepoints-to-string(xs:integer(.) + 65)" as="xs:string*"/>
<xsl:sequence select="string-join($padded-letter-seq, '')"/>
</xsl:function>
<xsl:function name="f:genId" as="xs:string">
<xsl:param name="pSeq" as="xs:integer"/>
<xsl:sequence select="f:genId($pSeq, 4)"/>
</xsl:function>
<xsl:template match="/">
<xsl:sequence select="f:genId(3)"/>
<xsl:sequence select="f:genId(3,5)"/>
</xsl:template>
</xsl:stylesheet>发布于 2021-03-12 12:26:31
只需使用 <xsl:sort> xslt元素,就像这样的
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<xsl:copy>
<xsl:apply-templates select="*">
<xsl:sort select="sequence"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>在所提供的XML文档上应用此转换时为
<list>
<item>
<sequence>1</sequence>
</item>
<item>
<sequence>2</sequence>
</item>
<item>
<sequence>3</sequence>
</item>
<item>
<sequence>4</sequence>
</item>
...
<item>
<sequence>14</sequence>
</item>
<item>
<sequence>15</sequence>
</item>
</list>生成所需的正确结果
<list>
<item>
<sequence>1</sequence>
</item>
<item>
<sequence>14</sequence>
</item>
<item>
<sequence>15</sequence>
</item>
<item>
<sequence>2</sequence>
</item>
<item>
<sequence>3</sequence>
</item>
<item>
<sequence>4</sequence>
</item>
</list>注意到
这一点:
<xsl:sort select="sequence"/>等同于:
<xsl:sort select="sequence" data-type="text"/>因为"text“是data-type属性的默认值。
如果需要按数字排序,则应显式使用:
<xsl:sort select="sequence" data-type="number"/>https://stackoverflow.com/questions/65397743
复制相似问题