tags:

views:

30

answers:

1

Note that I posed a very similar question earlier but the requirements have since changed

http://stackoverflow.com/questions/3842719/alphanumeric-sort-on-mixed-string-value

The primary difference in the requirements now is that the source XML can include forms with all alpha chars in the form_name or all integers.

The form_name can be open season as letters and numbers can be in any order:

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

Given XML of:

<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>  

The output should be:

<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>

The results should be in this order:

  1. Forms with integers only
  2. Forms that start of with integers but also include alpha characters (can include spaces)
  3. Forms that only include alpha characters
  4. Forms that start off with an alpha character but also include integers (can include spaces)

So like forms are grouped/sorted. I have tried various enhancements to the answers provided in my previous referenced question but have not hit upon the right filtering pattern for the sorts. XSLT 2.0 solutions are fine.

A: 

This XSLT 1.0 transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
 <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>

when applied to the provided XML file:

<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>

produces the wanted result:

<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>
Dimitre Novatchev