?
Solved

Write a variable number of sort selects?

Posted on 2011-10-19
4
Medium Priority
?
254 Views
Last Modified: 2013-11-18
Trying to sort a list with a custom character-by-character sort.

Sample input:
<items>
  <item>abc</item>
  <item>a!c</item>
  <item>a2c</item>
</items>

Desired output is sorted by letter, then number, then non-alphanumeric (exclamation mark, spaces etc). For each character.

The xsl below, with 3 sort selects per character, works. But it's ugly code, and to process sorting of unknown input I'd need to anticipate potential string-length of up to at least 50 characters....

I was hoping there'd be a way to iterate from $iterator to $length_second_longest_string, writing 3 sort selects for each character.
But I can't see how...


<xsl:variable name="alphabet" select="'abcdefghijklmnipqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
<xsl:variable name="numberic" select="'012345679'" />
<xsl:variable name="alphanumeric" select="concat($alphabet, $numberic)" />
<xsl:variable name="iterator" select="1" />
<xsl:variable name="length_second_longest_string">
      <xsl:for-each select="//item">
            <xsl:sort select="string-length(.)" order="descending" data-type="number" />
            <xsl:if test="position() = 2">
                  <xsl:value-of select="string-length(.)"/>
            </xsl:if>      
      </xsl:for-each>
</xsl:variable>

<xsl:template match="/">                              
      <xsl:for-each select="//item">
            <xsl:sort select="number(contains($alphanumeric, substring(.,1,1)))" order="descending" data-type="number" />
            <xsl:sort select="substring(.,1,1)" data-type="number" order="ascending" />
            <xsl:sort select="substring(.,1,1)" data-type="text" order="ascending" />
            
            <xsl:sort select="number(contains($alphanumeric, substring(.,2,1)))" order="descending" data-type="number" />
            <xsl:sort select="substring(.,2,1)" data-type="number" order="ascending" />
            <xsl:sort select="substring(.,2,1)" data-type="text" order="ascending" />
            
            <xsl:sort select="number(contains($alphanumeric, substring(.,3,1)))" order="descending" data-type="number" />
            <xsl:sort select="substring(.,3,1)" data-type="number" order="ascending" />
            <xsl:sort select="substring(.,3,1)" data-type="text" order="ascending" />
                        
            <xsl:copy-of select="."/>
      </xsl:for-each>            
</xsl:template>


All suggestions appreciated.
0
Comment
Question by:hc0904pcd
  • 2
  • 2
4 Comments
 
LVL 60

Accepted Solution

by:
Geert Bormans earned 2000 total points
ID: 36991878
Though I don't grasp the complete impact of what you are doing, I am pretty convinced you can just do this with one sort, not datatyped as number but datatyped on text.
What you need to do is remap the characters with translate() to the expected behaviour

this could be something like this
 <xsl:sort select="translate(.,'0123456789abcdABCD?./!', '?/.!aAbBcCdD0123456789')" order="descending" data-type="text" />

this is ofcourse just an example, but on remapping each character in your input onto a different character  you control the exact sort order per character

I don't know which behaviour you want and what your current processor does
In XSLT1 you depend on the sort of the underlying technology (could be java, .net, ...)
In XSLT2 you have a concpt of collations that help you to redefine sort behaviour.
That is more efficient, but programming a collation is not exactly easier than using translate to tweek

translate is key
here is how it works
each character in the first argument that is found at a location 'n' in the second argument gets replaced by the character at location 'n' in the third argument

note that numbers play their part in the sorting as text, unless you cast them

0
 
LVL 6

Author Comment

by:hc0904pcd
ID: 36992165
thank you :)
0
 
LVL 6

Author Comment

by:hc0904pcd
ID: 36992208
That was exactly the help I needed!


<xsl:variable name="sort_input"  select="'aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ012345679 ?!*'" />
<xsl:variable name="sort_output" select="' !*?012345679aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ'" />      
<xsl:template match="/">
      <items>
            <standard_sort>
                  <xsl:for-each select="//item">
                        <xsl:sort select="." />
                        <xsl:copy-of select="."/>
                  </xsl:for-each>
            </standard_sort>      
            <custom_sort>                  
                  <xsl:for-each select="//item">                  
                        <xsl:sort select="translate(., $sort_input, $sort_output)" data-type="text" order="ascending" />                                          
                        <xsl:copy-of select="." />
                  </xsl:for-each>            
            </custom_sort>      
      </items>      
</xsl:template>

input:
<items>
      <item>abc</item>
      <item>a!c</item>
      <item>a2c</item>
</items>

output:
<items>
      <standard_sort>
            <item>a!c</item>
            <item>a2c</item>
            <item>abc</item>
      </standard_sort>
      <custom_sort>
            <item>abc</item>
            <item>a2c</item>
            <item>a!c</item>
      </custom_sort>
</items>
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 36992215
welcome
0

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Most of the sites are being standardized with W3C Web Standards. W3C provides lot of web standard services to the web. They have the web specification, process and documentation for all the web standards. You can apply HTML, CSS and Accessibility st…
SASS allows you to treat your CSS code in a more OOP way. Let's have a look on how you can structure your code in order for it to be easily maintained and reused.
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.
Suggested Courses

864 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question