Jan*_*Doe 3 sorting xslt numerical
我必须按数字顺序整理代码.代码有四个字符和四个数字.
例如,
COMP2100
COMP2400
COMP3410
LAWS2202
LAWS2250
Run Code Online (Sandbox Code Playgroud)
当我这样做<xsl:sort select="code" order="ascending" />
时显示上面的结果.
但是,我希望它是'数字顺序'
COMP2100
LAWS2202
COMP2250
COMP2400
COMP3410
Run Code Online (Sandbox Code Playgroud)
我该怎么做呢?
注意:OP现在提供了示例XML.以下理论可以简单地适应这种XML.
I. XSLT 1.0(第1部分)
这是一个简单的解决方案,假设您的断言("代码有四个字符和四个数字")将始终如此:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output omit-xml-declaration="no" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:variable name="vNums" select="'1234567890'" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<t>
<xsl:apply-templates>
<xsl:sort select="substring(., 5)"
data-type="number" />
</xsl:apply-templates>
</t>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
...应用于想象的XML文档,随机排列:
<?xml version="1.0" encoding="utf-8"?>
<t>
<i>COMP3410</i>
<i>LAWS2202</i>
<i>COMP2400</i>
<i>COMP2100</i>
<i>LAWS2250</i>
</t>
Run Code Online (Sandbox Code Playgroud)
...产生了正确的结果:
<?xml version="1.0" encoding="utf-8"?>
<t>
<i>COMP2100</i>
<i>LAWS2202</i>
<i>LAWS2250</i>
<i>COMP2400</i>
<i>COMP3410</i>
</t>
Run Code Online (Sandbox Code Playgroud)
说明:
Identity Transform-的一个(如果不是该在XSLT)最根本的设计模式-将所有从源XML文档作为-是结果XML文档节点.<t>根据字符串中从第5位到字符串结尾的字符对所有子项进行排序来覆盖标识变换.再次注意,这个解决方案假设你的原始断言 - "代码有四个字符和四个数字" - 是(并且永远都是)真的.
II.XSLT 1.0(第2部分)
(可能)更安全的解决方案是假设<i>节点内的各个位置可能存在许多非数字字符.在这种情况下,这个XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output omit-xml-declaration="no" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:variable name="vNums" select="'1234567890'" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<t>
<xsl:apply-templates>
<xsl:sort select="translate(., translate(., $vNums, ''), '')"
data-type="number" />
</xsl:apply-templates>
</t>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
...提供相同的结果:
<?xml version="1.0" encoding="utf-8"?>
<t>
<i>COMP2100</i>
<i>LAWS2202</i>
<i>LAWS2250</i>
<i>COMP2400</i>
<i>COMP3410</i>
</t>
Run Code Online (Sandbox Code Playgroud)
说明:
Identity Transform再次使用.Double Translate Method(首先由Michael Kay提出并由Dimitre Novatchev首先向我显示)<i>在排序之前从每个元素的值中删除所有非数字字符.III.XSLT 2.0解决方案
这是一个可能的XSLT 2.0解决方案非常类似于XSLT 1.0解决方案的第2部分; 它只是用XPath 2.0处理正则表达式的能力取代了Double Translate方法:
<xsl:sort select="replace(., '[^\d]', '')" data-type="number" />
Run Code Online (Sandbox Code Playgroud)
请注意,您无需在XPath 2.0中使用正则表达式; Double Translate方法与XPath 1.0一样有效.replace()然而,该方法最有可能更有效.