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"/>
Большое спасибо
Решение
<xsl:sort select="(data[@alias='createdDate' and normalize-space() != '']|@createDate)[last()]" order="descending" />
Этот оператор создает набор узлов с двумя узлами, содержащими дату, и получает последний в соответствии с порядком документов для выполнения сортировки.Если данные узел существует и не является пустым, он будет использоваться для сортировки, поскольку дочерние элементы элемента происходят после его атрибутов nodes.
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"/>
Чтобы проверить, является ли узел пустым (или опущен) в XSLT:
<xsl:when test="not(string(name))">...</xsl:when>
<!-- or -->
<xsl:when test="not(name)">...</xsl:when>
Большое спасибо Эрлоку за его решение.Некоторое время я пытался заставить это работать в моей версии Umbraco (4.7.1) из-за изменений, внесенных в синтаксис Umbraco XSLT.
Для всех, кому интересно, мой рабочий образец изменил бы код Erlock на;
<xsl:sort select="(current()/createdDate[normalize-space() != '']|@createDate)[last()]" order="descending" />