给定以下XML片段:
<forms>
<FORM lob="BO" form_name="AI OM 10"/>
<FORM lob="BO" form_name="CL BP 03 01"/>
<FORM lob="BO" form_name="AI OM 107"/>
<FORM lob="BO" form_name="CL BP 00 02"/>
<FORM lob="BO" form_name="123 DDE"/>
<FORM lob="BO" form_name="CL BP 00 02"/>
<FORM lob="BO" form_name="AI OM 98"/>
</forms>我需要按字母顺序对表单节点进行排序,以便将form_name中包含'AI OM‘的所有表单分组在一起,然后在其中按整数的数字顺序排序(其他表单也是如此)。
form_name可以是开放的季节,因为字母和数字可以是任何顺序:
XX ## ##
XX XX ##
XX XX ###
XX XX ## ##
XX ###
XX XXXX
'## XXX
XXX###
我认为需要发生的是字符串需要在字母和数字之间拆分。我想,数字部分可能会在删除空格的情况下进行排序。
我不知道如何拆分字符串,然后覆盖所有的排序/分组组合,因为'form_name‘格式没有规则。
我们使用的是XSLT 2.0。谢谢。
发布于 2010-10-02 04:28:30
此转换
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vDigits" select="'0123456789 '"/>
<xsl:variable name="vAlpha" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ '"/>
<xsl:template match="/*">
<forms>
<xsl:for-each select="FORM">
<xsl:sort select="translate(@form_name,$vDigits,'')"/>
<xsl:sort select="translate(@form_name,$vAlpha,'')"
data-type="number"/>
<xsl:copy-of select="."/>
</xsl:for-each>
</forms>
</xsl:template>
</xsl:stylesheet>在所提供的XML文档上应用时的
<forms>
<FORM lob="BO" form_name="AI OM 10"/>
<FORM lob="BO" form_name="CL BP 03 01"/>
<FORM lob="BO" form_name="AI OM 107"/>
<FORM lob="BO" form_name="CL BP 00 02"/>
<FORM lob="BO" form_name="123 DDE"/>
<FORM lob="BO" form_name="CL BP 00 02"/>
<FORM lob="BO" form_name="AI OM 98"/>
</forms>生成所需的、正确的结果
<forms>
<FORM lob="BO" form_name="AI OM 10"/>
<FORM lob="BO" form_name="AI OM 98"/>
<FORM lob="BO" form_name="AI OM 107"/>
<FORM lob="BO" form_name="CL BP 00 02"/>
<FORM lob="BO" form_name="CL BP 00 02"/>
<FORM lob="BO" form_name="CL BP 03 01"/>
<FORM lob="BO" form_name="123 DDE"/>
</forms>注意到
<xsl:sort> instructions实现两阶段排序translate()函数用于生成仅字母排序关键字或仅数字排序关键字。发布于 2010-10-02 04:42:16
此样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="forms">
<xsl:apply-templates>
<xsl:sort select="normalize-space(
translate(@form_name,
'0123456789',
''))"/>
<xsl:sort select="substring-before(
concat(
normalize-space(
translate(@form_name,
translate(@form_name,
'0123456789 ',
''),
'')),
' '),' ')" data-type="number"/>
<xsl:sort select="substring-after(
normalize-space(
translate(@form_name,
translate(@form_name,
'0123456789 ',
''),
'')),
' ')" data-type="number"/>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>输出:
<FORM lob="BO" form_name="AI OM 10"></FORM>
<FORM lob="BO" form_name="AI OM 98"></FORM>
<FORM lob="BO" form_name="AI OM 107"></FORM>
<FORM lob="BO" form_name="CL BP 00 02"></FORM>
<FORM lob="BO" form_name="CL BP 00 02"></FORM>
<FORM lob="BO" form_name="CL BP 03 01"></FORM>
<FORM lob="BO" form_name="123 DDE"></FORM>XSLT 2.0解决方案:此样式表
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="forms">
<xsl:apply-templates>
<xsl:sort select="string-join(tokenize(@form_name,' ')
[not(. castable as xs:integer)],
' ')"/>
<xsl:sort select="xs:integer(tokenize(@form_name,' ')
[. castable as xs:integer][1])"/>
<xsl:sort select="xs:integer(tokenize(@form_name,' ')
[. castable as xs:integer][2])"/>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>发布于 2014-05-04 12:04:26
应该注意的是,标记答案并不是在所有情况下都有效。
输入:
<forms>
<FORM lob="BO" form_name="AA 11 AB"/>
<FORM lob="BO" form_name="AA AZ 01"/>
</forms>预期输出:
<forms>
<FORM lob="BO" form_name="AA AZ 01"/>
<FORM lob="BO" form_name="AA 11 AB"/>
</forms>实际输出:
<forms>
<FORM lob="BO" form_name="AA 11 AB"/>
<FORM lob="BO" form_name="AA AZ 01"/>
</forms>如果数字后面允许有字母,则不能在第一个排序关键字中将其去掉。
https://stackoverflow.com/questions/3842719
复制相似问题