#xslt
#xslt
Вопрос:
Мне нужно отобразить указанное количество элементов из источника XML, где значение элементов «DueDate» не указано. Вот пример xml:
<Items>
<Item>
<Title>Title 1</Title>
<DueDate>01-02-2008</DueDate>
</Item>
<Item>
<Title>Title 2</Title>
<DueDate>01-02-2009</DueDate>
</Item>
<Item>
<Title>Title 3</Title>
<DueDate>01-02-2010</DueDate>
</Item>
<Item>
<Title>Title 4</Title>
<DueDate>01-02-2011</DueDate>
</Item>
<Item>
<Title>Title 5</Title>
<DueDate>01-02-2012</DueDate>
</Item>
<Item>
<Title>Title 6</Title>
<DueDate>01-02-2013</DueDate>
</Item>
</Items>
Количество отображаемых элементов и текущая дата передаются в XSLT в качестве параметров.
Можно ли подсчитать количество отображаемых элементов в цикле for-each в Xslt? Или есть подход получше?
Примером может быть то, что ограничение было установлено на 3 элемента. В этом примере я ожидал бы увидеть следующие результаты: «Заголовок 3», «Заголовок 4» и «Заголовок 5».
Ответ №1:
Вы можете сделать что-то вроде этого. Превратите это в шаблон, который вы можете вызывать с параметрами:
<xsl:template match="/">
<xsl:variable name="count" select="3"/>
<xsl:for-each select="Items/Item">
<xsl:if test="position() amp;< $count">
<xsl:value-of select="Title"/> - <xsl:value-of select="DueDate"/>
</xsl:if>
</xsl:for-each>
Комментарии:
1. Но это не приведет к удалению элементов, у которых «DueDate» больше, чем сегодня? Это просто даст мне первые три элемента! Если я включу оператор if для проверки даты, будет показан только третий (position() == 3) «допустимый» элемент.
Ответ №2:
Попробуйте вложить это в стандартный xsl for-each, где n в вашем случае равно 3:
<xsl:if test="position() amp;< n">
Но если вы также хотите проверить дату, то вам нужно вложить другое if и создать даты в формате ггггММдд, которые можно сравнить численно следующим образом:
<xsl:variable name="secondDate" select="concat(substring(submissionDeadline, 1,4),substring(submissionDeadline, 6,2),substring(submissionDeadline, 9,2))"/>
<xsl:if test="$firstDate amp;> $secondDate">
Ответ №3:
Основная проблема заключается в том, что ваш входной XML-файл не соответствует полезному формату ‘гггг-мм-дд’. Это затрудняет сортировку / фильтрацию этих элементов в Жопа позади.
Если я вас правильно понял, вам необходимо
- сначала отфильтруйте по сроку выполнения
- после этого примените максимум к выходным данным
XPath для выбора всех <Item>
до определенного максимального срока выполнения будет выглядеть следующим образом:
Item[
substring-before(DueDate, '-')
amp;<=
substring-before($MaxDueDate, '-')
and
substring-before(substring-after(DueDate, '-'), '-')
amp;<=
substring-before(substring-after($MaxDueDate, '-'), '-')
and
substring-after(substring-after(DueDate, '-'), '-')
amp;<=
substring-after(substring-after($MaxDueDate, '-'), '-')
][
position() amp;<= $MaxCount
]
Теперь сравните это с тривиальным способом, если бы у вас были даты ‘гггг-мм-дд’:
Item[
DueDate amp;<= $MaxDueDate
][
position() amp;<= $MaxCount
]
Итак, чтобы скопировать только эти элементы, вы должны перейти:
<xsl:template match="Items">
<xsl:copy>
<xsl:copy-of select="
{ the expression I gave above }
" />
</xsl:copy>
</xsl:template>
Для значений параметров '01-02-2012'
и 4
, соответственно, я получаю:
<Items>
<Item>
<Title>Title 1</Title>
<DueDate>01-02-2008</DueDate>
</Item>
<Item>
<Title>Title 2</Title>
<DueDate>01-02-2009</DueDate>
</Item>
<Item>
<Title>Title 3</Title>
<DueDate>01-02-2010</DueDate>
</Item>
<Item>
<Title>Title 4</Title>
<DueDate>01-02-2011</DueDate>
</Item>
</Items>