tags:

views:

50

answers:

2

Hi ,

I want to sort in xslt based on existing set of pattern .

Let me explain with the code:

<Types>
  <Type>
     <Names>
      <Name>Ryan</Name>
     </Names>
      <Address>2344</Address>
   </Type>
    <Type>
      <Names>
       </Name>Timber</Name>
      </Names>
       <Address>1234</Address>
    </Type>
    <Type>
      <Names>
       </Name>Bryan</Name>
      </Names>
       <Address>34</Address>
    </Type>
</Types>

Right now I m just calling it and getting it like (all hyperlinks)

Ryan
Timber 
Bryan

Now I don't want sorting on name but I have existing pattern how I want it to get displayed.Like

Timber
Bryan
Ryan

(Also I don't want to lose the url attached to my names earlier while doing this)

I was thinking of putting earlier value in some array and sort based on the other array where I will store my existing pattern. But I am not sure how to achieve that..

My xslt looks like this now(there can be duplicate names also)

<xsl:for-each select="/Types/Type/Names/Name/text()[generate-id()=generate-id(key('Name',.)[1])]">
<xsl:call-template name="typename">
</xsl:call-template>
</xsl:for-each>

<xsl:template name="typename">

 <li>
<a href="somelogicforurl"> <xsl:value-of select="."/> </a>
 </li>

</xsl:template>

I am using xsl 1.0

+1  A: 

XSLT 1.0 has sorting capability. Try extrapolating this example:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;

  <xsl:template match="Types">
    <xsl:element name="SortedList">
      <xsl:for-each select="Type">
        <xsl:sort select="Names/Name" />
        <xsl:element name="a">
          <xsl:attribute name="href">link</xsl:attribute>
          <xsl:value-of select="Names/Name" />
        </xsl:element>
      </xsl:for-each>
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

I'm not sure what exactly you want to sort on, but just change the 'select' attribute of the xsl:sort tag to specify the sort key.

Alternatively, if you're trying to force a specific order, you could just brute force it:

  <xsl:template match="Types">
    <xsl:element name="SortedList">
      <xsl:apply-templates select="Names[Name='Timber']" />
      <xsl:apply-templates select="Names[Name='Bryan']" />
      <xsl:apply-templates select="Names[Name='Ryan']" />
    </xsl:element>
  </xsl:template>

  <xsl:template match="Names">
    <xsl:element name="a">
      <xsl:attribute name="href">link</xsl:attribute>
      <xsl:value-of select="Name" />
    </xsl:element>
  </xsl:template>

By doing this however, you run the risk of missing things out, or including things twice. The sort order's fairly flexible though, you could even sort on

<xsl:sort select="string-length(substring-before(';Timber;Bryan;Ryan',Names/Name))" />

This statement will return 1 for 'Timber', 8 for 'Bryan' (length of ';Timber;'), and 14 for 'Ryan' (length of ';Timber;Bryan;'), and you can sort by this to have them appear in the order you want. This solution would put any that you haven't included in your sort order at the top, as the 'substring-before' function would return an empty string, which of course has length 0. You do need to be careful however to make sure that you don't match prematurely if one happens to be a substring of another; for example if this was all lower case, you'd match 'ryan' too early, as it would pick up as part of 'bryan'.

Flynn1179
A: 

I think I have mentioned clearly that I just don't want to do sorting based on name. I want sorting based on the existing pattern I am having.

Teelo
What is that existing pattern? Is it also part of the same input XML?
Marc