1

Sorry if my explanation in the last 'question' was a little rough, I'll give it another shot.I'm really new to xsl.

Through a series of substrings I have extracted the date field by storing it in a variable called $releasedate, I output this by using <xsl:value-of select="$releasedate" /> which would display dd/mm/yyyy e.g. 29/03/2010 in a 'for each' loop as shown below.

My xml is structured similar to below,

<item>
<title>Title Goes Here</title>
<description>test goes here.....<b>Release Date:22/20/2010</b> more text</description>
</item>
<item>
<title>Title Goes Here</title>
<description>More test goes here.....<b>Release Date:22/20/2010</b> more text</description>
</item>

I would like to be able to sort by the value of what is stored in $releasedate. I think maybe it would look like this below

<xsl:sort select="$releasedate" order="descending" />

I hope this makes a little more sense, my appologies again for my lack of knowledge in this.

Below is my xsl structure

<xsl:for-each select="item">
    <xsl:sort select="pubDate"/>
    <xsl:if test="position() &lt; 5 ">
        <!-- grabs items 1 to 5 -->
        <xsl:variable name = "releasedatestart" >
            <xsl:value-of select="substring-after(description,'Release Date:&lt;/b&gt;')"/>
        </xsl:variable>
        <xsl:variable name = "releasedate" >
            <xsl:value-of select="substring-before($releasedatestart,'&lt;/div&gt;')"/>
        </xsl:variable>
        <xsl:variable name = "displaynamestart" >
            <xsl:value-of select="substring-after(description,'Display Name:&lt;/b&gt;')"/>
        </xsl:variable>
        <xsl:variable name = "displayname" >
            <xsl:value-of select="substring-before($displaynamestart,'&lt;/div&gt;')"/>
        </xsl:variable>
        <div style="margin:0px;background-color:#f2eff3;border:1px solid #ded6df;">
            <xsl:variable name = "start" >
                <xsl:value-of select="substring-after(description,'Description:&lt;/b&gt;')"/>
            </xsl:variable>
            <xsl:variable name = "title" >
                <xsl:value-of select="substring($start,0,100)"/>
            </xsl:variable>
            <xsl:variable name = "pagelink" >
                <xsl:value-of select="substring(link,1,61)"/>
            </xsl:variable>
            <xsl:variable name = "pageurl" >
                <xsl:value-of select="$pagelink"/>
                <xsl:value-of select="title"/>.aspx
            </xsl:variable>
            <div style="min-height:50px;">
                <div class="column" id="feeddate">
                    <xsl:value-of select="$releasedate" />
                </div>
                <div class="column" id="displayname">
                    <xsl:value-of select="$displayname" />
                </div>
                <div class="column" id="feedtitle">
                    <xsl:value-of select="$title" disable-output-escaping="yes"/>
                    <a>
                        <xsl:attribute name="href">
                            <xsl:value-of select="$pageurl" />
                        </xsl:attribute>
                        ..Read More
                    </a>
                </div>
            </div>
        </div>
    </xsl:if>
</xsl:for-each>
7
  • 2
    What do you mean by "sort the loop by this varible above?" Please provide more context. Commented Mar 23, 2011 at 22:14
  • @Andrew: Your question is not clear. Please, provide reduce input sample, complete desired output and bindings explanation. Commented Mar 24, 2011 at 2:29
  • 22/20/2010 seems weird. Which calendar has 20 months? Commented Mar 24, 2011 at 12:57
  • Good question, +1. See my answer for a complete, short and easy solution and explanation. Commented Mar 24, 2011 at 13:27
  • @Andrew: Why those encoded ends tags like &lt;/div&gt;? What's your real input? Commented Mar 27, 2011 at 15:34

1 Answer 1

1

This transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="items">
  <items>
    <xsl:apply-templates>
      <xsl:sort select=
      "substring(substring-after(description, 'Release Date:'),7)"
       data-type="number" order="descending"/>
      <xsl:sort select=
      "substring(substring-after(description, 'Release Date:'),4,2)"
       data-type="number" order="descending"/>
      <xsl:sort select=
      "substring(substring-after(description, 'Release Date:'),1,2)"
       data-type="number" order="descending"/>
     </xsl:apply-templates>
  </items>
 </xsl:template>
</xsl:stylesheet>

when applied on this document:

<items>
    <item>
        <title>Title1</title>
        <description>text1 .....
            <b>Release Date:22/12/2010</b> more text
        </description>
    </item>
    <item>
        <title>Title Goes Here</title>
        <description>More test goes here.....
            <b>Release Date:23/12/2010</b> more text
        </description>
    </item>
</items>

produces the wanted, sorted result:

<items>
   <item>
      <title>Title Goes Here</title>
      <description>More test goes here.....
            <b>Release Date:23/12/2010</b> more text
        </description>
   </item>
   <item>
      <title>Title1</title>
      <description>text1 .....
            <b>Release Date:22/12/2010</b> more text
        </description>
   </item>
</items>

Explanation:

  1. Use of substring-after() and substring().

  2. Multiple <xsl:sort> children of <xsl:apply-templates>.

  3. Identity transform.

Sign up to request clarification or add additional context in comments.

2 Comments

Hi Dimitre This script works fine, however I have some days where it will be 1/03/2011, rather than 01/03/2011. When this occurs the day substring will be put out of place. Is there a way around that?
@Andrew: Yes, then the select attribute of the three <xsl:sort> instructions will be: substring-after(substring-after(description, '/'), '/) , substring-before(substring-after(description, '/'), '/) and substring-before(description, '/')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.