重新访问混合字符串值的字母数字排序

时间:2010-10-18 17:10:09

标签: xml xslt xslt-2.0

请注意,我之前提出了一个非常相似的问题,但要求已经改变了

Alphanumeric sort on mixed string value

现在要求的主要区别在于源XML可以包含form_name中所有alpha字符或所有整数的表单。

form_name可以是开放季节,因为字母和数字可以是任何顺序:

XX ## ##
XX XX ##
XX XX ###
XX XX ## ##
XX ###
XX XXXX
## XXX
XXX###
XXX
###

给出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"/>
<FORM lob="BO" form_name="543 ZZE"/>
<FORM lob="BO" form_name="543 ABC"/>
<FORM lob="BO" form_name="256"/>
<FORM lob="BO" form_name="ABC"/>
</forms>  

输出应为:

<forms>
   <FORM lob="BO" form_name="256"/>
   <FORM lob="BO" form_name="123 DDE"/>
   <FORM lob="BO" form_name="543 ABC"/>
   <FORM lob="BO" form_name="543 ZZE"/>
   <FORM lob="BO" form_name="ABC"/>
   <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"/>
</forms>

结果应按此顺序排列:

  1. 仅包含整数的表单
  2. 以整数开头但包含字母字符(可包含空格)的表单
  3. 仅包含字母字符的表单
  4. 以字母字符开头但也包含整数(可包含空格)的表单
  5. 因此,表格被分组/排序。我已经尝试了对我之前引用的问题中提供的答案的各种增强,但没有找到适合的排序模式。 XSLT 2.0解决方案很好。

1 个答案:

答案 0 :(得分:0)

此XSLT 1.0转换

<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="vAlha" select=
  "' ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
  "/>
 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="/*">
  <forms>
    <xsl:apply-templates select="*[floor(@form_name) = floor(@form_name)]">
      <xsl:sort data-type="number"/>
    </xsl:apply-templates>

    <xsl:apply-templates select=
      "*[substring-before(@form_name,' ')
       and
         translate(substring-before(@form_name,' '),
                   ' 0123456789',
                   '')
        =
         ''
        ]">
      <xsl:sort select="substring-before(@form_name,' ')" data-type="number"/>
      <xsl:sort select="substring-after(@form_name,' ')"/>
    </xsl:apply-templates>

    <xsl:apply-templates select=
    "*[translate(@form_name,$vAlha,'')
      =
      ''
       ]">
       <xsl:sort select="@form_name"/>
    </xsl:apply-templates>

    <xsl:apply-templates select=
    "*[contains($vAlha,substring(@form_name,1,1))
     and
       not(translate(@form_name, $vAlha, '') = '')
       ]">
       <xsl:sort select="translate(@form_name, ' 0123456789', '')"/>
       <xsl:sort select="translate(@form_name, $vAlha, '')" data-type="number"/>
    </xsl:apply-templates>
  </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"/>
    <FORM lob="BO" form_name="543 ZZE"/>
    <FORM lob="BO" form_name="543 ABC"/>
    <FORM lob="BO" form_name="256"/>
    <FORM lob="BO" form_name="ABC"/>
</forms>

产生想要的结果

<forms>
    <FORM lob="BO" form_name="256"></FORM>
    <FORM lob="BO" form_name="123 DDE"></FORM>
    <FORM lob="BO" form_name="543 ABC"></FORM>
    <FORM lob="BO" form_name="543 ZZE"></FORM>
    <FORM lob="BO" form_name="ABC"></FORM>
    <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>
</forms>