XSLT - расчет суммы цены для выбранных узлов - PullRequest
0 голосов
/ 03 января 2019

У меня следующий код XML:

<?xml version="1.0" encoding="UTF-8"?>
<audioteka xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="audioteka.xsd">

<CD id="p1">
<title>Butchered at Birth</title>
<author>Cannibal Corpse</author>
<genre>Metal</genre>
<release_date>1991-06-30</release_date>
<price currency="PLN">49.99</price>
<publisher>
    <name>Napalm Records</name>
    <country>USA</country>
</publisher>
</CD>
<CD id = "p2">
<title>Battalions of Fear</title>
<author>Blind Guardian</author>
<genre>Metal</genre>
<release_date>1988-02-15</release_date>
<price currency="PLN">34.99</price>
<publisher>
    <name>BMG</name>
    <country>Belgia</country>
</publisher>
</CD>
<CD id = "p3">
<title>Dangerous Days</title>
<author>Perturbator</author>
<genre>Synthwave</genre>
<release_date>2014-09-17</release_date>
<price currency="EUR">52.99</price>
<publisher>
    <name>Mystic Productions</name>
    <country>Polska</country>
</publisher>
</CD>
</audioteka>

И этот код для преобразования XML с использованием xslt:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
version="1.0"
xmlns:a="http://www.test.com/">
<xsl:output method="xml" indent="yes"/>

<xsl:param name="Num" select="2"/>

<xsl:template match="audioteka">
     Zamowienie - faktura       
<xsl:for-each select="/audioteka/CD">
    <xsl:sort select="author" order="descending" />
    <xsl:if test="position() &lt;= $Num">
    Tytul: <xsl:value-of select="title"/>
    Autor: <xsl:value-of select="author"/>
    Gatunek: <xsl:value-of select="genre"/>
    Cena: <xsl:value-of select="price"/>
    ----------------------------------
    </xsl:if>     
</xsl:for-each>  

Но я не знаю, как рассчитать сумму названий и цен на 5 выбранных компакт-дисков.Я попытался использовать

Suma: <xsl:value-of select="sum(@price)"/>

, но это дает мне неправильные значения.У кого-нибудь была идея для решения?

1 Ответ

0 голосов
/ 05 января 2019

Идея решения этой проблемы:

  • Сохранение необходимых элементов в переменной.
  • Запустите цикл for-each, извлекая содержимое из этой переменной.
  • Суммируйте цены также из этой переменной.

Небольшое усложнение заключается в том, что в XSLT 1.0 тип этой переменной равен Фрагмент дерева результатов (RTF) , поэтому он не можетбыть непосредственно использованным в XPath выражениях.

Чтобы обойти это ограничение, вы должны использовать функцию exsl:node-set, конвертируя такие RTF в набор узлов и затем используйте его в XPath .

Таким образом, весь скрипт может выглядеть следующим образом:

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:exsl="http://exslt.org/common"
  extension-element-prefixes="exsl">
  <xsl:output method="text"/>

  <xsl:param name="Num" select="2"/>

  <xsl:template match="/">
    <xsl:variable name="discs">
      <xsl:for-each select="audioteka/CD">
        <xsl:sort select="author" order="descending"/>
        <xsl:if test="position() &lt;= $Num">
          <xsl:copy-of select="."/>
        </xsl:if>
      </xsl:for-each>
    </xsl:variable>
    <xsl:text>Zamowienie - faktura&#x0A;&#x0A;</xsl:text>
    <xsl:for-each select="exsl:node-set($discs)/CD">
      <xsl:value-of select="concat('Tytul:   ', title, '&#x0A;')"/>
      <xsl:value-of select="concat('Autor:   ', author, '&#x0A;')"/>
      <xsl:value-of select="concat('Gatunek: ', genre, '&#x0A;')"/>
      <xsl:value-of select="concat('Cena:    ', price, '&#x0A;')"/>
      <xsl:text>----------------------------------&#x0A;</xsl:text>
    </xsl:for-each>
    <xsl:value-of select="concat('Suma:    ', sum($discs/CD/price),
      '&#x0A;')"/>
  </xsl:template>
</xsl:stylesheet>

Как вы можете видеть, я также внес некоторые исправления, касающиеся генерации вывода.

Первое, на что нужно обратить внимание, это метод вывода = text , потому что вы генерируете «обычный» текст, а не XML.

Еще одно изменение заключается в том, что для вывода текста Iиспользуйте xsl:text и &#x0A; для перевода строки.Преимущество состоит в том, что отступ кода (и текста) в скрипте не влияет на отступ вывода.

Рабочий пример см. http://xsltransform.net/3MP2uBx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...