xslt 1 и функция суммы - PullRequest
       39

xslt 1 и функция суммы

2 голосов
/ 16 сентября 2011

Я создаю систему управления счетами, используя xml и PHP, но последняя версия PHP не поддерживает XSLT 2.0 - поэтому я должен искать альтернативу sum ().Как я могу преобразовать действительную функцию xslt 2 «сумма (единица цены * количество)» в xslt 1.0?

Материал XML основан на Примеры Джона

Я попробовал его с набором узлов, но он не поддерживается "xmlXPathCompOpEval: набор функций не найден«

Ответы [ 3 ]

6 голосов
/ 16 сентября 2011

На самом деле, sum(price*quantity) не является допустимым синтаксисом XSLT 2.0. Я предполагаю, что вы имеете в виду что-то вроде `сумма (для $ х в * возврат $ х / цена * $ х / количество).

Суммирование по вычисленному значению в XSLT 1.0 может быть выполнено следующими способами:

  • двухпроходное решение, создайте набор узлов, в котором узлы содержат вычисленные значения, затем суммируйте по набору узлов

  • рекурсивное решение: написать рекурсивный шаблон, который передает сумму до параметра, добавляет сумму * количество для текущего узла, а затем рекурсивно обрабатывать оставшиеся узлы

  • решение высшего порядка: используйте библиотеку FXSL Дмитрия Новатчева

  • решение расширения: используйте такие функции расширения, как saxon: sum ()

1 голос
/ 17 сентября 2011

В XSLT 1.0 вы можете использовать функцию / шаблон FXSL * map() (и либо функцию sum() FXSL, либо стандартную XPath sum()) , так какпоказано в следующем примере:

Имея этот XML-документ :

<sales>
  <sale>
    <price>3.5</price>
    <quantity>2</quantity>
    <Discount>0.75</Discount>
    <Discount>0.80</Discount>
    <Discount>0.90</Discount>
  </sale>
  <sale>
    <price>3.5</price>
    <quantity>2</quantity>
    <Discount>0.75</Discount>
    <Discount>0.80</Discount>
    <Discount>0.90</Discount>
  </sale>
</sales>

, мы хотим получить сумму от всех продаж - это суммапродукты: price* quantity * discount1 * discount2 ...* discountN для каждой продажи.

Это преобразование XSLT 1.0 :

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
xmlns:ext="http://exslt.org/common"
xmlns:test-map-product="test-map-product"
exclude-result-prefixes="xsl f ext test-map-product"
>
   <xsl:import href="sum.xsl"/>
   <xsl:import href="map.xsl"/>
   <xsl:import href="product.xsl"/>

   <!-- This transformation is to be applied on:
        salesMap.xml

        It contains the code of the "sum of products" from the 
        article "The Functional Programming Language XSLT"
     -->

   <test-map-product:test-map-product/>

   <xsl:output method="text"/>

   <xsl:template match="/">
     <!-- Get: map product /sales/sale -->
     <xsl:variable name="vSalesTotals">
         <xsl:variable name="vTestMap" select="document('')/*/test-map-product:*[1]"/>
         <xsl:call-template name="map">
           <xsl:with-param name="pFun" select="$vTestMap"/>
           <xsl:with-param name="pList1" select="/sales/sale"/>
         </xsl:call-template>
     </xsl:variable>

     <!-- Get sum map product /sales/sale -->
      <xsl:call-template name="sum">
        <xsl:with-param name="pList" select="ext:node-set($vSalesTotals)/*"/>
      </xsl:call-template>
   </xsl:template>

    <xsl:template name="makeproduct" mode="f:FXSL"
      match="test-map-product:*">
      <xsl:param name="arg1"/>

      <xsl:call-template name="product">
        <xsl:with-param name="pList" select="$arg1/*"/>
      </xsl:call-template>
    </xsl:template>
</xsl:stylesheet>

при применении к вышеуказанному XML-документу создает искомую,правильный результат :

7.5600000000000005

II.Решение XPath 2.0 :

Упрощенная проблема (первоначально опубликованная) может быть решена с помощью простой однострочной XPath 2.0.Если у нас есть этот XML-документ:

<sales>
  <sale>
    <price>3.5</price>
    <quantity>2</quantity>
  </sale>
  <sale>
    <price>3.5</price>
    <quantity>2</quantity>
  </sale>
</sales>

, то это выражение XPath 2.0 :

sum(/*/sale/(price*quantity))

при оценке выдает требуемую сумму :

14

Вот проверка этого факта на основе XSLT 2.0:

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/*">
     <xsl:sequence select="sum(sale/(price*quantity))"/>
 </xsl:template>
</xsl:stylesheet>

Когда это преобразование выполняется над XML-документом выше, желаемый, правильный результат выдается :

14
1 голос
/ 16 сентября 2011

Вы можете просто создать шаблон sumNumbers, который добавляет две величины. Дополнение может быть выполнено в операторе выбора:

<xsl:template name="sumNumbers">
    <xsl:param name="num1"/>
    <xsl:param name="num2"/>

    <xsl:value-of select="$num1 + $num2" />
</xsl:template>

должно работать

...