Как сортировать элементы и сохранять их в переменной XSLT

StackOverflow https://stackoverflow.com/questions/2272123

Вопрос

Мне было интересно, возможно ли сначала отсортировать некоторые элементы и сохранить их (уже отсортированные) в переменной.Мне нужно было бы ссылаться на них в 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].

Я был бы признателен за любую помощь и советы!

Большое спасибо!

Это было полезно?

Решение

Во-первых, в объявлении вашей переменной вам действительно нужно что-то сделать для создания новых узлов.Строго говоря, вы не сортируете их, а просто читаете в определенном порядке.Я думаю, вам нужно добавить какую-то команду 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 one.

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

Вот хорошая статья для чтения о наборах узлов

Xml.com статья о наборах узлов

Другие советы

  1. Используя XSLT version 2.0 вы могли бы использовать perform-sort и скажите, что ваша переменная имеет тип последовательности MultiDeposits используя as keyword (as="element(MultiDeposits)+")
  2. Поскольку ваши данные уже представлены в формате гггг-мм-дд, вы можете избежать использования подстроки для получения каждой части даты и использовать сортировку непосредственно по полю

с помощью этого примера 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>

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top