Question

I have a for each which loops round news item nodes. Among other properties these news items have two attributes for created date. System added date and a user entered created date (to override the system date). I would like the list sorted by created date with the preference on the user entered date.

Below is my humble invalid attempt!

<xsl:for-each select="$currentPage/ancestor-or-self::node /node [@nodeTypeAlias = $documentTypeAlias and string(data [@alias='umbracoNaviHide']) != '1']">

<xsl:choose>
 <xsl:when test="data [@alias = 'createdDate'] != ''">
  <xsl:variable name="sort" select="string(data [@alias = 'createdDate'])"/>
 </xsl:when>
 <xsl:otherwise>
  <xsl:variable name="sort" select="string(@createDate)"/>
 </xsl:otherwise>
</xsl:choose>

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

Many thanks

Was it helpful?

Solution

<xsl:sort select="(data[@alias='createdDate' and normalize-space() != '']|@createDate)[last()]" order="descending" />

This statement creates a nodeset with the two nodes containing date, and get the last one according the document order to do the sorting. If data node exists and is not empty, it will be used for the sorting because child elements of an element occur after its attribute nodes.

concat() can only work, and in a few cases, if you use text sorting; it will fail with numeric sorting.

OTHER TIPS

Right, seems like a hack but I have been able to achieve this by using a concat with the sort.

Example below

<xsl:for-each select="$currentPage/ancestor-or-self::node /node [@nodeTypeAlias = $documentTypeAlias and string(data [@alias='umbracoNaviHide']) != '1']">
<xsl:sort select="concat(data [@alias = 'createdDate'],@createDate)" order="descending"/>

To test if a node is empty (or omitted) in XSLT:

<xsl:when test="not(string(name))">...</xsl:when>
<!-- or -->
<xsl:when test="not(name)">...</xsl:when>

Many thanks to Erlock for his solution. I did struggle for a while to get this working in my version of Umbraco (4.7.1) due to the changes made to the Umbraco XSLT syntax.

For anyone interested, my working sample would change Erlock's code to become;

<xsl:sort select="(current()/createdDate[normalize-space() != '']|@createDate)[last()]" order="descending" />
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top