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

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

Материал XML основан на примерах Джона

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

    На самом деле sum(price*quantity) недопустима синтаксисом XSLT 2.0. Наверное, вы имеете в виду что-то вроде `sum (для $ x in * return $ x / price * $ x / quantity).

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

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

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

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

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

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

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

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

    В XSLT 1.0 вы можете использовать функцию / шаблон FXSL map() (и функцию sum() FXSL или стандартную функцию sumath 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