2009-11-08 46 views
0

对于每个循环的新闻项目节点,我都有一个值。在其他属性中,这些新闻项目具有创建日期的两个属性。系统添加日期和用户输入创建日期(覆盖系统日期)。我希望根据用户输入日期的偏好,按创建日期排序。XSLT如果第一个为空,则对第二个值应用排序

下面是我谦虚无效的尝试!

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

非常感谢

+0

umbraco ftw。我有很多戏剧在xslt中进行条件排序。 – ChadT 2009-11-09 09:02:35

回答

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

此语句创建与含有日期的两个节点的节点集,并根据文件顺序获取最后一个进行排序。如果数据节点存在并且不为空,则它将用于排序,因为元素的子元素出现在其属性节点之后。

concat()只能工作,在少数情况下,如果使用文本排序;它会通过数字排序失败。

+0

我认为这工作,但仔细检查它不完全。如果存在具有createdDate别名的数据节点,则它会使用它,但如果不存在,则不使用@createDate。对此有何想法?似乎更强大的使用concat,所以我想坚持下去。 – Max 2009-11-11 23:27:34

+0

一点点的信息。我认为数据节点确实存在,但它是空的。在这种情况下,我想使用@createDate。 – Max 2009-11-12 21:41:24

+0

好的,你只是没有暴露一切。 ;) 如果不能选择空数据节点进行排序,则必须修改谓词。我编辑了我的答案。 – Erlock 2009-11-13 09:20:26

0

权,似乎是一个黑客,但我已经能够通过使用CONCAT进行排序,以实现这一目标。

实施例下面

<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"/> 
0

为了在XSLT测试一个节点是空的(或忽略):

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

非常感谢Erlock的解决方案。由于对Umbraco XSLT语法进行了更改,我在一段时间内努力争取在我的Umbraco版本(4.7.1)中工作。

对于任何有兴趣的人来说,我的工作示例会更改Erlock的代码;

<xsl:sort select="(current()/createdDate[normalize-space() != '']|@createDate)[last()]" order="descending" /> 
相关问题