基于XSLT中分组的计算问题

问题描述 投票:0回答:1

在这里,我需要从一个节点获取一个存在的值并将其用于值的计算。

这是我的XML:

<?xml version="1.0" encoding="utf-8"?>
<Document>
  <Header>
    <FirstName>Joel</FirstName>
    <LastName>Cabarles</LastName>
    <InvoiceDate>01-JAN-2020</InvoiceDate>
    <InvoiceNumber>123</InvoiceNumber>
    <Currency>PHP</Currency>
    <ExchangeRate>1.5</ExchangeRate>
  </Header>
  <InvoiceLines>
    <Lines>
      <LineNumber>1</LineNumber>
      <Description>Test1</Description>
      <Quantity>200</Quantity>
      <UnitPrice>500</UnitPrice>
      <Amounts>
        <Net>100000</Net>
        <VATRate>
          <Percent>2</Percent>
        </VATRate>
        <VATAmount>2000</VATAmount>
        <Gross>102000</Gross>
      </Amounts>
      <Extra>
        <ExchangeRate>1.5</ExchangeRate>
      </Extra>
    </Lines>
    <Lines>
      <LineNumber>2</LineNumber>
      <Description>Test2</Description>
      <Quantity>300</Quantity>
      <UnitPrice>1000</UnitPrice>
      <Amounts>
        <Net>300000</Net>
        <VATRate>
          <Percent>3</Percent>
        </VATRate>
        <VATAmount>9000</VATAmount>
        <Gross>309000</Gross>
      </Amounts>
      <Extra>
        <ExchangeRate>2</ExchangeRate>
      </Extra>
    </Lines>
    <Lines>
      <LineNumber>3</LineNumber>
      <Description>Test3</Description>
      <Quantity>100</Quantity>
      <UnitPrice>500</UnitPrice>
      <Amounts>
        <Net>50000</Net>
        <VATRate>
          <Percent>3</Percent>
        </VATRate>
        <VATAmount>1500</VATAmount>
        <Gross>51500</Gross>
      </Amounts>
      <Extra>
        <ExchangeRate>3</ExchangeRate>
      </Extra>
    </Lines>
    <Lines>
      <LineNumber>4</LineNumber>
      <Description>Test4</Description>
      <Quantity>100</Quantity>
      <UnitPrice>500</UnitPrice>
      <Amounts>
        <Net>50000</Net>
        <VATRate>
          <Excempt>0</Excempt>
        </VATRate>
        <VATAmount>0</VATAmount>
        <Gross>50000</Gross>
      </Amounts>
      <Extra>
        <ExchangeRate>1.2</ExchangeRate>
      </Extra>
    </Lines>
  </InvoiceLines>
</Document>

您可以看到,在Document/Header/ExchangeRate部分以及Document/InvoiceLines/Lines/Extra/ExchangeRate部分中都有一个ExhangeRate标签>

如果Document/InvoiceLines/Lines/Extra/ExchangeRate节不存在,则应始终取自Document/Header/ExchangeRate中的值

但是使用下面的XSLT1.0,它总是采用标记Document/InvoiceLines/Lines/Extra/ExchangeRate的第一个实例:

<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"/>
  <xsl:strip-space elements="*"/>

  <xsl:key name="amt-by-rate" match="Amounts" use="VATRate/*" />
  <xsl:variable name="Curr" select="//Header/Currency" />
  <xsl:decimal-format name="decFormat" decimal-separator="." grouping-separator="," NaN="0.00"/>
  <xsl:decimal-format name="XRFormat" decimal-separator="." grouping-separator="," NaN="1.00"/>

  <xsl:template match="Document">
    <Invoice>
      <xsl:apply-templates select ="Header" />
      <xsl:apply-templates select ="InvoiceLines" />
      <xsl:call-template name="Summary" />
    </Invoice>
  </xsl:template>

  <xsl:template match="InvoiceLines">
    <InvoiceDetails>
      <xsl:apply-templates select ="Lines" />
    </InvoiceDetails>

  </xsl:template>

  <xsl:template match ="Lines">
    <InvLine>
      <Number>
        <xsl:value-of select="LineNumber"/>
      </Number>
      <UnitPrice>
        <xsl:value-of select="Amount"/>
      </UnitPrice>
      <Quantity>
        <xsl:value-of select="Quantity"/>
      </Quantity>
      <Amounts>
        <xsl:copy-of select="Amounts/VATRate"/>
        <xsl:call-template name="Amounts">
          <xsl:with-param name="SectionName" select="'LineAmountData'" />
          <xsl:with-param name="FieldName" select="'LineAmount'" />
          <xsl:with-param name="Data" select="Amounts/Net" />
        </xsl:call-template>
        <xsl:call-template name="Amounts">
          <xsl:with-param name="SectionName" select="'LineVATData'" />
          <xsl:with-param name="FieldName" select="'VATAmount'" />
          <xsl:with-param name="Data" select="Amounts/VATAmount" />
        </xsl:call-template>
        <xsl:call-template name="Amounts">
          <xsl:with-param name="SectionName" select="'LineGrossData'" />
          <xsl:with-param name="FieldName" select="'GrossAmount'" />
          <xsl:with-param name="Data" select="Amounts/Gross" />
        </xsl:call-template>
      </Amounts>
    </InvLine>
  </xsl:template>

  <xsl:template name="Summary">
    <InvoiceSummary>
      <xsl:variable name="amounts" select="InvoiceLines/Lines/Amounts" />
      <Summary>
        <xsl:for-each select="$amounts[count(. | key('amt-by-rate', VATRate/*)[1]) = 1]">
          <xsl:variable name="current-group" select="key('amt-by-rate', VATRate/*)" />
          <Rate>
            <xsl:copy-of select="VATRate"/>
            <xsl:call-template name="Amounts">
              <xsl:with-param name="SectionName" select="'NetAmountData'" />
              <xsl:with-param name="FieldName" select="'NetAmount'" />
              <xsl:with-param name="Data" select="sum($current-group/Net)" />
            </xsl:call-template>
            <xsl:call-template name="Amounts">
              <xsl:with-param name="SectionName" select="'VATAmountData'" />
              <xsl:with-param name="FieldName" select="'VATAmount'" />
              <xsl:with-param name="Data" select="sum($current-group/VATAmount)" />
            </xsl:call-template>
            <xsl:call-template name="Amounts">
              <xsl:with-param name="SectionName" select="'GrossAmountData'" />
              <xsl:with-param name="FieldName" select="'GrossAmount'" />
              <xsl:with-param name="Data" select="sum($current-group/Gross)" />
            </xsl:call-template>
          </Rate>
        </xsl:for-each>
      </Summary>
      <xsl:call-template name="Amounts">
        <xsl:with-param name="SectionName" select="'InvoiceNetAmountData'" />
        <xsl:with-param name="FieldName" select="'InvoiceNetAmount'" />
        <xsl:with-param name="Data" select="sum($amounts/Net)" />
      </xsl:call-template>
      <xsl:call-template name="Amounts">
        <xsl:with-param name="SectionName" select="'InvoiceVATAmountData'" />
        <xsl:with-param name="FieldName" select="'InvoiceVATAmount'" />
        <xsl:with-param name="Data" select="sum($amounts/VATAmount)" />
      </xsl:call-template>
      <xsl:call-template name="Amounts">
        <xsl:with-param name="SectionName" select="'InvoiceGrossAmountData'" />
        <xsl:with-param name="FieldName" select="'InvoiceGrossAmount'" />
        <xsl:with-param name="Data" select="sum($amounts/Gross)" />
      </xsl:call-template>
    </InvoiceSummary>
  </xsl:template>

  <xsl:template match="Header">
    <InvoiceHeader>
      <Name>
        <xsl:value-of select="concat(FirstName,' ',LastName)" />
      </Name>
      <InvoiceDate>
        <xsl:value-of select="InvoiceDate" />
      </InvoiceDate>
      <InvoiceNumber>
        <xsl:value-of select="InvoiceNumber" />
      </InvoiceNumber>
    </InvoiceHeader>
  </xsl:template>

  <xsl:template name ="Amounts">
    <xsl:param name="SectionName" />
    <xsl:param name="FieldName" />
    <xsl:param name="DecimalPrecision" />
    <xsl:param name="Data" />

    <xsl:variable name="xRate">
      <xsl:choose>
        <xsl:when test="//Extra/ExchangeRate[position()]!=''">
          <xsl:value-of select ="format-number(//Extra/ExchangeRate,'#0.000','XRFormat')"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="format-number(//Header/ExchangeRate,'#0.000','XRFormat')"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <xsl:choose>
      <xsl:when test="$SectionName!=''">
        <xsl:element name="{$SectionName}">
          <xsl:element name="{$FieldName}">
            <xsl:value-of select="format-number($Data, '#0.00' ,'decFormat')" />
          </xsl:element>
          <xsl:element name="{$FieldName}PHP">
            <xsl:value-of select="format-number($Data * $xRate, '#0.00','decFormat')" />
          </xsl:element>
        </xsl:element>
      </xsl:when>
      <xsl:otherwise>
        <xsl:element name="{$FieldName}">
          <xsl:value-of select="format-number($Data, '#0.00','decFormat')" />
        </xsl:element>
        <xsl:element name="{$FieldName}PHP">
          <xsl:value-of select="format-number($Data * $xRate, '#0.00','decFormat')" />
        </xsl:element>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

现在,我总是得到下面的第一个表,但是我需要的是在第二个表中得到结果:enter image description here

任何人都可以帮助我确定这是什么问题。

感谢,顺便说一句,我需要使用XSLT 1.0。

我这里有一种情况,我需要从存在的节点获取值并将其用于计算值。这是我的XML:<...>]

xml xslt xslt-1.0
1个回答
0
投票

我想代替

 <xsl:when test="//Extra/ExchangeRate[position()]!=''">
© www.soinside.com 2019 - 2024. All rights reserved.