转换使用前一行的值,但不应该

时间:2013-12-22 19:39:37

标签: xml xslt

我在XML中有一个简单的价目表:

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="example.xsl" type="text/xsl"?>
<price-items>
<item><name>item 1</name>   <price-b2b vat='no'>10</price-b2b><price-b2c vat='no'>20</price-b2c></item>
<item><name>item 2</name>   <price-b2b vat='yes'>100</price-b2b><price-b2c vat='yes'>200</price-b2c></item>
<item><name>item 3</name>   <price-b2b vat='no'>1000</price-b2b><price-b2c vat='no'>2000</price-b2c></item>
</price-items>

附加的样式表看起来是这样的:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xsl:stylesheet  [
    <!ENTITY nbsp   "&#160;">
]>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:decimal-format decimal-separator="," grouping-separator=" "/>
  <xsl:output method="xml" encoding="utf-8" indent="yes" />
  <xsl:variable name="vat" select="1.21" />
<xsl:template match="/">
<?xml-stylesheet href="example.css" type="text/css"?>
<price-items> <xsl:apply-templates /></price-items>
</xsl:template>

<xsl:template match="item">
<item><xsl:apply-templates /></item>
</xsl:template>

<xsl:template match="name">
<name><xsl:apply-templates /></name>
</xsl:template>

<xsl:template match="item">
<item>
    <xsl:for-each select="price-b2b">
        <xsl:choose>
            <xsl:when test="@vat='no'">
            <price-b2b vat="no">b2b excl. VAT: <xsl:value-of select="." />&nbsp;unit(s)</price-b2b>
            <price-b2b vat="yes">b2b s vat <xsl:value-of select="format-number(number(/price-items/item/price-b2b * $vat), '# ###,##')" />&nbsp;unit(s)</price-b2b>
            </xsl:when>

            <xsl:when test="@vat='yes'">
            <price-b2b vat="no">b2b excl. VAT: <xsl:value-of select="format-number(number(/price-items/item/price-b2b div $vat), '# ###,##')" />&nbsp;unit(s)</price-b2b>
            <price-b2b vat="yes">b2b incl. VAT: <xsl:apply-templates />&nbsp;unit(s)</price-b2b>
            </xsl:when>
        </xsl:choose>
    </xsl:for-each>


    <xsl:for-each select="price-b2c">    
        <xsl:choose>
        <xsl:when test="@vat='no'">
        <price-b2c vat="no">b2c excl. VAT: <xsl:apply-templates />&nbsp;unit(s)</price-b2c>
        <price-b2c vat="yes">b2c incl. VAT: <xsl:value-of select="format-number(number(/price-items/item/price-b2c * $vat), '# ###,##')" />&nbsp;unit(s)</price-b2c>
        </xsl:when>

        <xsl:when test="@vat='yes'">
        <price-b2c vat="no">b2c price excl. VAT: <xsl:value-of select="format-number(number(/price-items/item/price-b2c div $vat), '# ###,##')" />&nbsp;unit(s)</price-b2c>
        <price-b2c vat="yes">b2c price incl. VAT: <xsl:apply-templates />&nbsp;unit(s)</price-b2c>
        </xsl:when>
    </xsl:choose>
    </xsl:for-each>

</item>

</xsl:template>

</xsl:stylesheet>

输出是这个(IE9中的动态转换,为了清楚起见,这里添加了一些格式):

b2b excl. VAT: 10 unit(s)
b2b s vat 12,1 unit(s)
b2c excl. VAT: 20 unit(s)
b2c incl. VAT: 24,2 unit(s)

b2b excl. VAT: 8,26 unit(s)
b2b incl. VAT: 100 unit(s)
b2c price excl. VAT: 16,53 unit(s)
b2c price incl. VAT: 200 unit(s)

b2b excl. VAT: 1000 unit(s)
b2b s vat 12,1 unit(s)
b2c excl. VAT: 2000 unit(s)
b2c incl. VAT: 24,2 unit(s)

在涉及计算的第2行和第3行中,它使用第一行(第一项)的值计算,而不是使用实际行中的相应值计算。

为什么?我该如何纠正?

1 个答案:

答案 0 :(得分:2)

进行计算时:

<xsl:value-of select="format-number(number(/price-items/item/price-b2b * $vat), '# ###,##')" />

这将始终为您提供第一项的价格(从技术上讲,/price-items/item/price-b2b是一个节点集,其中包含所有来自每个price-b2b元素item,当您获取具有多个节点的节点集的数值时,它仅使用集合中的 first 节点并忽略其他节点。

但是在样式表的这一点上,您for-each的上下文节点已经是price-b2b元素,因此您应该执行类似

的操作
<xsl:value-of select="format-number(number(. * $vat), '# ###,##')" />

同样适用于其他三个案例。