У меня есть структура xml, например:
<PartsDetail> <Id>1481</Id> <Desc>test1</Desc> <GlobDesc>test2</GlobDesc> <Price Cur="UAH">+798.27</Price> </PartsDetail> <PartsDetail> <Id>0741</Id> <Desc>test2</Desc> <GlobDesc>test2</GlobDesc> <Price Cur="UAH">+399.14</Price> </PartsDetail>
И, на мой взгляд, я делаю некоторые преобразования с «ценой» (я предлагаю посмотреть, как 399.14).
Я использую это для преобразования:
<xsl:call-template name="showNumberWithThousands"> <xsl:with-param name="value"> <xsl:call-template name="parseNumber"> <xsl:with-param name="value" select="Price"/> </xsl:call-template> </xsl:with-param> </xsl:call-template>
Также мне нужно взять сумму цены сейчас. Я попытался использовать это:
<xsl:value-of select="sum(//Data/Paint//PartsDetail/@Price)"/>
Но результат – NaN.
Насколько я понимаю, мне нужно преобразовать цену в «нормальном представлении (без + и -)» перед отправкой функции «sum».
Кому: @ michael.hor257k
Структура сложнее. Я использую ваше решение, но оно не работает. Похоже, я что-то делаю неправильно
<xsl:template name="PaintSum"> <xsl:variable name="corrected-prices"> <xsl:for-each select="//CalcData/Paint/PaintDtl"> <price> <xsl:value-of select="translate(MatAmnt, '+', '')"/> </price> </xsl:for-each> </xsl:variable> <sum> <xsl:value-of select="sum(exsl:node-set($corrected-prices)/price)"/> </sum> </xsl:template>
И когда я использую <xsl:call-template name="PaintSum"/>
Ничего не происходит. Аналогичным образом, дальнейший запрос в шаблоны перестает работать.
Я пытаюсь использовать:
<xsl:variable name="corrected-prices"> <xsl:for-each select="//CalcData/Paint//PaintDtl"> <price> <xsl:value-of select="translate(MatAmnt, '+', '')"/> </price> </xsl:for-each> </xsl:variable>
И добавьте сумму в текст:
<xsl:value-of select="sum(exsl:node-set($corrected-prices)/price)"/>
Но выходной файл – сбой.
$ скорректированные цены содержат «1086.65286.75».
Как я могу превратить это в сумму?
Насколько я понимаю, мне нужно преобразовать цену в «нормальный вид (без + и -)» перед отправкой функции «sum».
Это более или менее корректно (вы не хотите удалять знак минуса, если число отрицательно). Учитывая хорошо сформированный ввод, такой как:
XML
<root> <PartsDetail> <Id>1481</Id> <Desc>test1</Desc> <GlobDesc>test2</GlobDesc> <Price Cur="UAH">+798.27</Price> </PartsDetail> <PartsDetail> <Id>0741</Id> <Desc>test2</Desc> <GlobDesc>test2</GlobDesc> <Price Cur="UAH">+399.14</Price> </PartsDetail> </root>
следующая таблица стилей:
XSLT 1.0
<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="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:template match="/root"> <xsl:variable name="corrected-prices"> <xsl:for-each select="PartsDetail"> <price> <xsl:value-of select="translate(Price, '+', '')"/> </price> </xsl:for-each> </xsl:variable> <sum> <xsl:value-of select="sum(exsl:node-set($corrected-prices)/price)"/> </sum> </xsl:template> </xsl:stylesheet>
вернется:
<?xml version="1.0" encoding="UTF-8"?> <sum>1197.41</sum>
Это преобразование не требует использования каких-либо функций расширения и не создает промежуточное дерево – на самом деле оно работает с 0 дополнительной памятью и подходит для потоковой передачи, если XSLT-процессор распознает хвостовую рекурсию:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:template match="/*"> <xsl:apply-templates select="(*/Price/text())[1]"> <xsl:with-param name="pNodes" select="*/Price/text()"/> </xsl:apply-templates> </xsl:template> <xsl:template match="text()" name="sum"> <xsl:param name="pTotal" select="0"/> <xsl:param name="pNodes"/> <xsl:param name="pNode1" select="translate($pNodes[1],'+','')"/> <xsl:value-of select="substring($pTotal+$pNode1, 1 div not($pNodes[2]))"/> <xsl:apply-templates select="$pNodes[2][$pNode1]"> <xsl:with-param name="pTotal" select="$pTotal+$pNode1"/> <xsl:with-param name="pNodes" select="$pNodes[position()>1]"/> </xsl:apply-templates> </xsl:template> </xsl:stylesheet>
Когда он применяется к предоставленному XML-документу :
<root> <PartsDetail> <Id>1481</Id> <Desc>test1</Desc> <GlobDesc>test2</GlobDesc> <Price Cur="UAH">+798.27</Price> </PartsDetail> <PartsDetail> <Id>0741</Id> <Desc>test2</Desc> <GlobDesc>test2</GlobDesc> <Price Cur="UAH">+399.14</Price> </PartsDetail> </root>
Выбранный, правильный результат получается :
1187.4099999999998