Пример: есть список книг, с указанием стоимости и дополнительный параметр - тип книги.
<books> <book author="Багряк П." cost="123" type="old"> Синие люди</book> <book author="Булгаков М." cost="34" type="old"> Роковые яйца</book> <book author="Чехов А.П." cost="23" type="old"> Чайка</book> <book author="Ленин В.И." cost="344" type="old"> Апрельские тезисы</book> <book author="Бондарев Ю." cost="23" type="old"> Берег</book> <book author="Булгаков М." cost="34" type="old"> Собачье сердце</book> <book author="Донцова Д." cost="237" type="new"> Кулинар</book> <book author="Булгаков М." cost="34" type="old"> Бег</book> <book author="Чехов А.П." cost="23" type="old"> Палата #6</book> <book author="Лесков Н." cost="744" type="old"> Левша</book> <book author="Гаррисон Г." cost="120" type="new"> Мир Родины</book> <book author="Ленин В.И." cost="344" type="old"> Что делать</book> </books>
|
Необходимо посчитать количество и стоимость старых (old) и новых (new) книг, их общую стоимость, определить самую дорогую и самую дешевую из книг.
Пример.1 Cумма и количество в XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output indent="yes"/> <xsl:template match="books"> <table> <tr> <td> Товар</td> <td> Количество</td> <td> Стоимость</td> </tr> <tr> <td> Старые книги</td> <td> <xsl:value-of select="count(book[@type = 'old']/@cost)"/> </td> <td> <xsl:value-of select="sum(book[@type = 'old']/@cost)"/> </td> </tr> <tr> <td> Новые книги</td> <td> <xsl:value-of select="count(book[@type = 'new']/@cost)"/> </td> <td> <xsl:value-of select="sum(book[@type = 'new']/@cost)"/> </td> </tr> <tr> <td> Итого</td> <td> <xsl:value-of select="count(book/@cost)"/> </td> <td> <xsl:value-of select="sum(book/@cost)"/> </td> </tr> </table> </xsl:template> </xsl:stylesheet>
|
Пример нуждается в комментариях? Вроде нет. Тогда переходим ко второму примеру, который решим двумя способами:
Пример 2a. XSLT min/max по-тупому
Определение минимума и максимума в традиционом програмировании решаются прогоном массива через цикл. В XSLT примерно то же самое, но со своими особенностями:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output indent="yes"/> <xsl:template match="books">
<xsl:for-each select="book/@cost"> <! -- задаем порядок сортировки по убыванию цены --> <xsl:sort data-type="number" order="descending"/> <! -- первый элемент выбранный в списке - это максимум --> <xsl:if test="position()=1"> MAX:<xsl:value-of select="."/> </xsl:if> </xsl:for-each> <! -- повторение - мать учения. В принципе MAX можно было воткнуть в предыдущий цикл --> <xsl:for-each select="book/@cost"> <xsl:sort data-type="number" /> <xsl:if test="position()=1"> MIN:<xsl:value-of select="."/> </xsl:if> </xsl:for-each> </xsl:template> </xsl:stylesheet>
|
Пример 2b. XSLT min/max вариант без использования for-each
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output indent="yes"/> <xsl:template match="books"> <!-- организуем перебор книг без использования оператора цикла. --> <xsl:apply-templates > <!-- задаем направление перебора --> <xsl:sort data-type="number" order="descending" select="@cost "/> </xsl:apply-templates> </xsl:template>
<xsl:template match="book"> <!-- отлавливаем первый и последний элементы списка book --> <xsl:choose> <xsl:when test="position() = 1"> MIIN:<xsl:value-of select="@cost"/> </xsl:when> <xsl:when test="position() = last() "> MAX:<xsl:value-of select="@cost"/> </xsl:when> </xsl:choose> <!-- а остальные элементы просто игнорируем --> </xsl:template>
</xsl:stylesheet>
|
Исходные коды в директории ex1 архива xslt-examples.zip