我有这个xml
<Process>
<name>name1</name>
<ListOfItems>
<item name="name2" price="10" quantity="1" value=""></item>
<item name="name7" price="10" quantity="2" value=""></item>
<item name="name12" price="10" quantity="3" value=""></item>
<item name="name17" price="10" quantity="4" value=""></item>
</ListOfItems>
<taxType>TEN</taxType>
</Process>
我希望输出
<ProcessResponse>
<name>name1</name>
<ListOfItems>
<item name="name2" price="10" quantity="1" value="10"></item>
<item name="name7" price="10" quantity="2" value="20"></item>
<item name="name12" price="10" quantity="3" value="30"></item>
<item name="name17" price="10" quantity="4" value="40"></item>
</ListOfItems>
<totalAmount>100</totalAmount>
<taxAmount>10</taxAmount>
<grandTotal>110</grandTotal>
</ProcessResponse>
它的发票目的,一些额外的信息:
我从2天开始做了很多研究,并使用了一些模板 获取totalAmount但它在浏览器测试器上工作但在“jdeveloper”转换中没有。 我知道问题出在模板匹配
浏览器<xsl:template match="/Process/ListOfItems">
中的工作但不在jdev中
即使<xsl:template match="/">
无效
请帮助解决这个问题,
提前致谢。
答案 0 :(得分:2)
在XSLT 2.0
内,计算值的sum()
要容易得多,但在XSLT 1.0
内它有点棘手,请参阅下一个XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<!-- Identity template -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<!-- Rename root node -->
<xsl:template match="Process">
<ProcessResponse>
<xsl:apply-templates select="@*|node()" />
</ProcessResponse>
</xsl:template>
<!-- Match on ListOfItems, to add new elements after it -->
<xsl:template match="ListOfItems">
<!-- Copy existing -->
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
<!-- Create the new elements -->
<xsl:apply-templates select="item[1]" mode="sumValue" />
</xsl:template>
<!-- Match on item element to do the calculation of value attribute -->
<xsl:template match="item">
<xsl:copy>
<!-- Copy existing attributes -->
<xsl:apply-templates select="@*" />
<!-- Actual calculation -->
<xsl:attribute name="value">
<xsl:value-of select="@quantity * @price" />
</xsl:attribute>
<!-- Copy rest of nodes -->
<xsl:apply-templates select="node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="item" mode="sumValue">
<xsl:param name="currentSumValue" select="0" />
<!-- Variable to store the updated sum value -->
<xsl:variable name="updatedSumValue" select="$currentSumValue + (@quantity * @price)" />
<!-- Proceed summing with the next item-->
<xsl:apply-templates select="following-sibling::item[1]" mode="sumValue">
<xsl:with-param name="currentSumValue" select="$updatedSumValue" />
</xsl:apply-templates>
<!-- No more items. Summing is complete, we can display the totalAmount and calculate the rest -->
<xsl:if test="not(following-sibling::item)">
<totalAmount><xsl:value-of select="$updatedSumValue"/></totalAmount>
<!-- taxAmount -->
<xsl:variable name="taxAmount">
<xsl:choose>
<xsl:when test="/Process/taxType = 'TEN'">
<xsl:value-of select="$updatedSumValue * (10 div 100)" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$updatedSumValue" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<taxAmount><xsl:value-of select="$taxAmount" /></taxAmount>
<!-- grandTotal -->
<grandTotal><xsl:value-of select="$updatedSumValue + $taxAmount" /></grandTotal>
</xsl:if>
</xsl:template>
<!-- Remove element taxType -->
<xsl:template match="taxType" />
</xsl:stylesheet>
在输入XML上应用时,结果为:
<?xml version="1.0" encoding="UTF-8"?>
<ProcessResponse>
<name>name1</name>
<ListOfItems>
<item name="name2" price="10" quantity="1" value="10"/>
<item name="name7" price="10" quantity="2" value="20"/>
<item name="name12" price="10" quantity="3" value="30"/>
<item name="name17" price="10" quantity="4" value="40"/>
</ListOfItems>
<totalAmount>100</totalAmount>
<taxAmount>10</taxAmount>
<grandTotal>110</grandTotal>
</ProcessResponse>
希望它有所帮助,并且de XSLT中的评论可以帮助您...
答案 1 :(得分:1)
使用XSLT 1.0的另一个版本,但它使用扩展函数
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
exclude-result-prefixes="ext"
version="1.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:variable name="tmpvalue">
<xsl:for-each select="//item">
<value><xsl:value-of select="@price*@quantity"/></value>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="taxAmount">
<!-- set you tax formula here -->
<xsl:value-of select="'10'"/>
</xsl:variable>
<xsl:template match="Process">
<ProcessResponse>
<xsl:apply-templates/>
<totalAmount>
<xsl:variable name="myValue" select="ext:node-set($tmpvalue)"/>
<xsl:value-of select="sum($myValue/value)"/>
</totalAmount>
<taxAmount><xsl:value-of select="$taxAmount"/></taxAmount>
<grandTotal>
<xsl:variable name="myValue" select="ext:node-set($tmpvalue)"/>
<xsl:value-of select="sum($myValue/value) + $taxAmount"/>
</grandTotal>
</ProcessResponse>
</xsl:template>
<xsl:template match="item">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:attribute name="value"><xsl:value-of select="@price*@quantity"/></xsl:attribute>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分:1)
我也会使用EXSLT node-set()函数,只使用较少的模板:
<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:param name="taxRate" select=".06"/>
<xsl:template match="/Process">
<ProcessResponse>
<xsl:copy-of select="name"/>
<xsl:variable name="items">
<xsl:for-each select="ListOfItems/item">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:attribute name="value">
<xsl:value-of select="@price*@quantity" />
</xsl:attribute>
</xsl:copy>
</xsl:for-each>
</xsl:variable>
<ListOfItems>
<xsl:copy-of select="$items"/>
</ListOfItems>
<xsl:variable name="total" select="sum(exsl:node-set($items)/item/@value)" />
<totalAmount><xsl:value-of select="$total" /></totalAmount>
<taxAmount><xsl:value-of select="$total*$taxRate" /></taxAmount>
<grandTotal><xsl:value-of select="$total*(1 + $taxRate)" /></grandTotal>
</ProcessResponse>
</xsl:template>
</xsl:stylesheet>