Как сортировать элементы и хранить их в переменной XSLT
Мне было интересно, можно ли сначала отсортировать некоторые элементы и сохранить их (уже отсортированные) в переменной. Мне нужно сослаться на них, подумал XSLT, поэтому я хотел бы хранить их в переменной.
Я пытался сделать следующее, но это не сработало
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:variable name="deposits">
<xsl:for-each select="/BookingCostings/MultiDeposits">
<xsl:sort select="substring(@DepositDate, 1, 4)" />
<xsl:sort select="substring(@DepositDate, 6, 2)" />
<xsl:sort select="substring(@DepositDate, 9, 2)" />
</xsl:for-each>
</xsl:variable>
Я пытался отсортировать элементы по @DepositDate
в формате "гггг-мм-дд" и сохраните их все в $deposits
переменная. Чтобы потом я мог получить к ним доступ, используя $deposits[1]
,
Буду признателен за любую помощь и советы!
Большое спасибо!
3 ответа
Во-первых, в объявлении переменной вам нужно что-то сделать для создания новых узлов. Строго говоря, вы не сортируете их, а просто читаете их в заданном порядке. Я думаю, что вам нужно добавить какую-то команду xsl: copy.
<xsl:variable name="deposits">
<xsl:for-each select="/BookingCostings/MultiDeposits">
<xsl:sort select="substring(@DepositDate, 1, 4)" />
<xsl:sort select="substring(@DepositDate, 6, 2)" />
<xsl:sort select="substring(@DepositDate, 9, 2)" />
<xsl:copy-of select=".|@*" />
</xsl:for-each>
</xsl:variable>
Это создает "набор узлов", но для доступа к нему вам потребуется использовать функцию расширения в XSLT. Какой из них вы используете, зависит от используемого вами процессора XSLT. В примере, который я собираюсь привести, я использую Microsoft.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ms="urn:schemas-microsoft-com:xslt" version="1.0">
Затем, чтобы получить доступ к узлам в вашей переменной, вы можете сделать что-то вроде этого
<xsl:value-of select="ms:node-set($deposits)/MultiDeposits[1]/@DepositDate" />
Вот хорошая статья для чтения о наборах узлов
- С помощью
XSLT version 2.0
вы могли бы использоватьperform-sort
и сказать, что ваша переменная имеет тип последовательностиMultiDeposits
с использованиемas keyword
(as="element(MultiDeposits)+
") - Поскольку ваши данные уже в формате гггг-мм-дд, вы можете избежать использования подстроки для получения каждой части даты и использовать сортировку непосредственно в поле
с этим примером XML:
<?xml version="1.0" encoding="ISO-8859-1"?>
<BookingCostings>
<MultiDeposits depositDate="2001-10-09">1</MultiDeposits>
<MultiDeposits depositDate="1999-10-09">2</MultiDeposits>
<MultiDeposits depositDate="2010-08-09">3</MultiDeposits>
<MultiDeposits depositDate="2010-07-09">4</MultiDeposits>
<MultiDeposits depositDate="1998-01-01">5</MultiDeposits>
</BookingCostings>
и используя лист XSLT версии 2.0:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<xsl:variable name="deposits" as="element(MultiDeposits)+">
<xsl:perform-sort select="BookingCostings/MultiDeposits">
<xsl:sort select="@depositDate"/>
</xsl:perform-sort>
</xsl:variable>
first date:<xsl:value-of select="$deposits[1]/@depositDate"/>,
last date:<xsl:value-of select="$deposits[last()]/@depositDate"/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
результат будет:
first date:1998-01-01, last date:2010-08-09
Угадайте (не иметь dev env под рукой):
добавлять <xsl:value-of select="." />
До закрытия </xsl:for-each>