Я создаю систему управления счетами с использованием 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