Xml XSLT-对逗号分隔字符串重新排序
我希望有人能帮忙。我有一个逗号分隔的字符串,如Xml XSLT-对逗号分隔字符串重新排序,xml,xslt,sorting,xslt-2.0,Xml,Xslt,Sorting,Xslt 2.0,我希望有人能帮忙。我有一个逗号分隔的字符串,如A10、A12、A11、S10、S11、S12这需要重新排序为S10、A10、S11、A11、S12、A12 排序标准如下: 每次都是在A之前 年数的增长顺序是10年前9年前11年前12年前13年等 因此,对于输入XML: <root> <row>A10,A12,A11,S10,S11,S12</row> </root> A10,A12,A11,S10,S11,S12 期望输出: &l
A10、A12、A11、S10、S11、S12
这需要重新排序为S10、A10、S11、A11、S12、A12
排序标准如下:
- 每次都是在A之前
- 年数的增长顺序是10年前9年前11年前12年前13年等
<root>
<row>A10,A12,A11,S10,S11,S12</row>
</root>
A10,A12,A11,S10,S11,S12
期望输出:
<root>
<row>S10,A10,S11,A11,S12,A12</row>
</root>
S10、A10、S11、A11、S12、A12
在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>
在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>
请注意:
A8,A10,A12,A11,S9,S10,S11,S12
A8,S9,S10,A10,S11,A11,S12,A12
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>
<root>
<row>A10,A12,A11,S10,S11,S12</row>
</root>
这个问题中的需求不包括某些可能的输入,因此,Michael Kay的两个当前解决方案和这个解决方案可以产生不同的结果
前者产生的结果总是按数字排序(并且可能违反交替的S
,a
要求)
此解决方案产生的结果是,S
和a
始终按此顺序交替,但可能并不总是满足数字排序要求
示例1:
A8,A10,A12,A11,S9,S10,S11,S12
A8,S9,S10,A10,S11,A11,S12,A12
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>
<root>
<row>A10,A12,A11,S10,S11,S12</row>
</root>
迈克尔·凯的解决方案产生了:
A8,A10,A12,A11,S9,S10,S11,S12
A8,S9,S10,A10,S11,A11,S12,A12
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>
<root>
<row>A10,A12,A11,S10,S11,S12</row>
</root>
这里“总是在(交替)之前”的要求没有得到满足
当前解决方案产生以下结果:
A8,A10,A12,A11,S9,S10,S11,S12
A8,S9,S10,A10,S11,A11,S12,A12
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>
<root>
<row>A10,A12,A11,S10,S11,S12</row>
</root>
这里满足了替换要求,但没有满足数字排序要求
此转换:
A8,A10,A12,A11,S9,S10,S11,S12
A8,S9,S10,A10,S11,A11,S12,A12
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>
<root>
<row>A10,A12,A11,S10,S11,S12</row>
</root>
应用于提供的XML文档时:
A8,A10,A12,A11,S9,S10,S11,S12
A8,S9,S10,A10,S11,A11,S12,A12
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>
<root>
<row>A10,A12,A11,S10,S11,S12</row>
</root>
A10,A12,A11,S10,S11,S12
生成所需的正确结果:
<root>
<row>S10,A10,S11,A11,S12,A12</row>
</root>
S10、A10、S11、A11、S12、A12
请注意:
A8,A10,A12,A11,S9,S10,S11,S12
A8,S9,S10,A10,S11,A11,S12,A12
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>
<root>
<row>A10,A12,A11,S10,S11,S12</row>
</root>
这个问题中的需求不包括某些可能的输入,因此,Michael Kay的两个当前解决方案和这个解决方案可以产生不同的结果
前者产生的结果总是按数字排序(并且可能违反交替的S
,a
要求)
此解决方案产生的结果是,S
和a
始终按此顺序交替,但可能并不总是满足数字排序要求
示例1:
A8,A10,A12,A11,S9,S10,S11,S12
A8,S9,S10,A10,S11,A11,S12,A12
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>
<root>
<row>A10,A12,A11,S10,S11,S12</row>
</root>
迈克尔·凯的解决方案产生了:
A8,A10,A12,A11,S9,S10,S11,S12
A8,S9,S10,A10,S11,A11,S12,A12
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>
<root>
<row>A10,A12,A11,S10,S11,S12</row>
</root>
这里“总是在(交替)之前”的要求没有得到满足
当前解决方案产生以下结果:
A8,A10,A12,A11,S9,S10,S11,S12
A8,S9,S10,A10,S11,A11,S12,A12
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>
<root>
<row>A10,A12,A11,S10,S11,S12</row>
</root>
这里满足了替换要求,但没有满足数字排序要求
此转换:
A8,A10,A12,A11,S9,S10,S11,S12
A8,S9,S10,A10,S11,A11,S12,A12
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>
<root>
<row>A10,A12,A11,S10,S11,S12</row>
</root>
应用于提供的XML文档时:
A8,A10,A12,A11,S9,S10,S11,S12
A8,S9,S10,A10,S11,A11,S12,A12
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>
<root>
<row>A10,A12,A11,S10,S11,S12</row>
</root>
A10,A12,A11,S10,S11,S12
生成所需的正确结果:
<root>
<row>S10,A10,S11,A11,S12,A12</row>
</root>
S10、A10、S11、A11、S12、A12
MMKD,这两个要求可能是矛盾的。例如,如果我们有A9、A10、A12、A11、S10、S11、S12
并且希望数值部分在结果中按递增顺序排列,那么A9
将出现在任何Sn
之前。请解释这种情况下的预期结果是什么?这不是问题,因为只有一个9
。只要9在10之前,这就不是问题。第一个排序应该是年,所以9、10、11、12
然后第二个排序应该是S然后N
。我可能更容易将其转换……A9=“秋2009”和S10=“夏季2010”这样,即使S应该在A之前,但由于year.MMKD的原因,这两个要求可能是矛盾的。例如,如果我们有A9、A10、A12、A11、S10、S11、S12
,并且希望结果中的数字部分按递增顺序排列,那么A9
将出现在任何Sn
之前。请解释一下在这种情况下,预期结果是什么?这不是问题,因为只有一个9
。只要9在10之前,这就不是问题。第一个排序应该是年,所以9,10,11,12
然后第二个排序应该是S然后N
。我可能更容易转换它……A9=“Autumn2009”和S10=“Summer2010”这样的话,你会认为S10之前是A9,尽管S应该在A之前,因为今年。