-1

我需要一种方法来计算每个客户的发票总数,(添加三张发票,然后相应地显示总数),尝试过 sum(/*/(PriceUnit*Ordered)),但它不起作用,.---[一张发票的总和=PriceUnit*Ordered],.so总结三张发票然后显示结果,.这对我来说很难所以请帮忙

样本输入文件

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="Nom.xslt"?>
<customers>
  <customer>
    <clientname>troy madison</clientname>
    <invoices>
    <invoiceDate>8/8/98</invoiceDate>
      <product>
         <PriceUnit>1000</PriceUnit>
         <Ordered>2</Ordered>
     </product>
     <product>
         <PriceUnit>5400</PriceUnit>
         <Ordered>3</Ordered>
     </product>
   </invoices>
   <invoices>
     <invoiceDate>1/4/98</invoiceDate>
       <product>
          <PriceUnit>300</PriceUnit>
          <Ordered>4</Ordered>
       </product>
      <product>
        <PriceUnit>6000</PriceUnit>
        <Ordered>1</Ordered>
     </product>
   </invoices>
  <invoices>
    <invoiceDate>03/5/99</invoiceDate>
      <product>
        <PriceUnit>549</PriceUnit>
        <Ordered>1</Ordered>
     </product>
     <product>
       <PriceUnit>320</PriceUnit>
       <Ordered>2</Ordered>
    </product>
   </invoices>
 </customer>
 <customer>
   <clientname>Morris</clientname>
    <invoices>
      <invoiceDate>1/1/00</invoiceDate>
        <product>
           <PriceUnit>59</PriceUnit>
           <Ordered>3</Ordered>
        </product>
      <product>
          <PriceUnit>55</PriceUnit>
          <Ordered>1</Ordered>
      </product>
    </invoices>
    <invoices>
     <invoiceDate>11/1/01</invoiceDate>
       <product>
         <PriceUnit>10</PriceUnit>
         <Ordered>2</Ordered>
      </product>
      <product>
         <PriceUnit>54</PriceUnit>
         <Ordered>1</Ordered>
       </product>
    </invoices>
    <invoices>
      <invoiceDate>03/2/01</invoiceDate>
        <product>
          <PriceUnit>30</PriceUnit>
          <Ordered>1</Ordered>
        </product>
       <product>
         <PriceUnit>299</PriceUnit>
         <Ordered>1</Ordered>
       </product>
    </invoices>
</customer>
</customers>

预期产出

[OP 在此处列出预期输出。]

到目前为止我尝试过的样式表

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="customers">
    <html>
        <head>
            <h1>CUSTOMER REFERENCE</h1>
        </head>
        <body bgcolor="#DAF52C">
            <table border="1">
                <tr>
                    <th width="50">NAME</th>
                    <th width="50">INVOICE DATE</th>
                    <th width="50">PRODUCT UNIT</th>
                    <th width="50">ORDERED </th>
                    <th width="50">PRODUCT UNIT</th>
                    <th width="50">ORDERED </th>
                    <th width="50">INVOICE DATE</th>
                    <th width="50">PRODUCT UNIT</th>
                    <th width="50">ORDERED </th>
                    <th width="50">PRODUCT UNIT</th>
                    <th width="50">ORDERED </th>
                    <th width="50">INVOICE DATE</th>
                    <th width="50">PRODUCT UNIT</th>
                    <th width="50">ORDERED </th>
                    <th width="50">PRODUCT UNIT</th>
                    <th width="50">ORDERED </th>
                    <th width="50">INVOICE TOTAL</th>
                </tr>
                <xsl:for-each select="customer">
                    <tr>
                        <td><xsl:value-of select="clientname"/></td>
                        <xsl:for-each select="invoices">
                            <td><xsl:value-of select="invoiceDate"/></td>
                            <xsl:for-each select="product">
                                <td><xsl:value-of select="PriceUnit"/></td>
                                <td><xsl:value-of select="Ordered"/></td>
                            </xsl:for-each>
                        </xsl:for-each>
                    </tr>
                </xsl:for-each>
            </table>
        </body>
    </html>
</xsl:template>
</xsl:stylesheet>
4

2 回答 2

0

Here is a pure XSLT 1.0 solution that doesn't require any extension functions:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/*">
  <html>
    <table border="1">
     <thead>
       <tr>
         <td>Name</td><td>Total</td>
       </tr>
     </thead>
     <xsl:apply-templates/>
    </table>
  </html>
 </xsl:template>

 <xsl:template match="customer">
  <tr>
    <td><xsl:value-of select="clientname"/></td>
    <td>
      <xsl:call-template name="sumProducts">
       <xsl:with-param name="pNodes" select="invoices/product"/>
       <xsl:with-param name="pName1" select="'PriceUnit'"/>
       <xsl:with-param name="pName2" select="'Ordered'"/>
      </xsl:call-template>
    </td>
  </tr>
 </xsl:template>

 <xsl:template name="sumProducts">
   <xsl:param name="pNodes"/>
   <xsl:param name="pName1"/>
   <xsl:param name="pName2"/>
   <xsl:param name="pAccum" select="0"/>

   <xsl:choose>
     <xsl:when test="not($pNodes)">
       <xsl:value-of select="$pAccum"/>
     </xsl:when>
     <xsl:otherwise>
      <xsl:call-template name="sumProducts">
        <xsl:with-param name="pNodes" select="$pNodes[position() >1]"/>
        <xsl:with-param name="pName1" select="$pName1"/>
        <xsl:with-param name="pName2" select="$pName2"/>
        <xsl:with-param name="pAccum" select=
        "$pAccum + $pNodes[1]/*[name()=$pName1] * $pNodes[1]/*[name()=$pName2]"/>
      </xsl:call-template>
     </xsl:otherwise>
   </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the provided XML document:

<customers>
    <customer>
        <clientname>troy madison</clientname>
        <invoices>
            <invoiceDate>8/8/98</invoiceDate>
            <product>
                <PriceUnit>1000</PriceUnit>
                <Ordered>2</Ordered>
            </product>
            <product>
                <PriceUnit>5400</PriceUnit>
                <Ordered>3</Ordered>
            </product>
        </invoices>
        <invoices>
            <invoiceDate>1/4/98</invoiceDate>
            <product>
                <PriceUnit>300</PriceUnit>
                <Ordered>4</Ordered>
            </product>
            <product>
                <PriceUnit>6000</PriceUnit>
                <Ordered>1</Ordered>
            </product>
        </invoices>
        <invoices>
            <invoiceDate>03/5/99</invoiceDate>
            <product>
                <PriceUnit>549</PriceUnit>
                <Ordered>1</Ordered>
            </product>
            <product>
                <PriceUnit>320</PriceUnit>
                <Ordered>2</Ordered>
            </product>
        </invoices>
    </customer>
    <customer>
        <clientname>Morris</clientname>
        <invoices>
            <invoiceDate>1/1/00</invoiceDate>
            <product>
                <PriceUnit>59</PriceUnit>
                <Ordered>3</Ordered>
            </product>
            <product>
                <PriceUnit>55</PriceUnit>
                <Ordered>1</Ordered>
            </product>
        </invoices>
        <invoices>
            <invoiceDate>11/1/01</invoiceDate>
            <product>
                <PriceUnit>10</PriceUnit>
                <Ordered>2</Ordered>
            </product>
            <product>
                <PriceUnit>54</PriceUnit>
                <Ordered>1</Ordered>
            </product>
        </invoices>
        <invoices>
            <invoiceDate>03/2/01</invoiceDate>
            <product>
                <PriceUnit>30</PriceUnit>
                <Ordered>1</Ordered>
            </product>
            <product>
                <PriceUnit>299</PriceUnit>
                <Ordered>1</Ordered>
            </product>
        </invoices>
    </customer>
</customers>

the wanted, correct result is produced:

<html>
   <table border="1">
      <thead>
         <tr>
            <td>Name</td>
            <td>Total</td>
         </tr>
      </thead>
      <tr>
         <td>troy madison</td>
         <td>26589</td>
      </tr>
      <tr>
         <td>Morris</td>
         <td>635</td>
      </tr>
   </table>
</html>

Explanation:

  1. A recursively called named template (sumProducts), which takes as parameters a node-set ($pNodes) of the nodes whose children's products should be summed and the names of the two children elements ($pName1 and $pName2), the products of whose values should be summed. There is a last, auxiliary parameter $pAccum with initial value 0, that is used to store the accumulated result between each recursive call.

  2. Stop condition is when the passed pNodes nodeset is empty. In this case we output the accumulated sum ($pAccum).

  3. If the stop condition is false, we call ourselves with $pNodes in which the first node is removed, and with a new value of $pAccum, to which we have added the current product.

Do note:

The sumProducts template is very generic and can be used in any case where sum of products is required.

Thus it deserves to be placed in its own stylesheet file, that will be imported by other stylesheets whenever sum of products is needed.

于 2012-09-09T15:30:37.573 回答
0

这是Dimitre对您第一次发布此问题的回答的 XSLT 1.0 等效版本。

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:exsl="http://exslt.org/common"
  xmlns:so="https://stackoverflow.com/questions/12338944"
  exclude-result-prefixes="xsl exsl so">
<xsl:output method="html" />
<xsl:strip-space elements="*" />

 <xsl:template match="/*">
  <html>
    <table border="1">
     <thead>
       <tr>
         <td>Name</td><td>Total</td>
       </tr>
     </thead>
     <xsl:apply-templates/>
    </table>
  </html>
 </xsl:template>

 <xsl:template match="customer">
  <tr>
    <td><xsl:value-of select="clientname"/></td>
    <td>
      <xsl:variable name="sales">
        <xsl:for-each select="invoices/product">
          <so:sale><xsl:value-of select="PriceUnit * Ordered"/></so:sale>
        </xsl:for-each>
      </xsl:variable>
      <xsl:value-of select="sum(exsl:node-set($sales)/so:sale)"/>
      </td>
  </tr>
 </xsl:template>
</xsl:stylesheet>

在示例文档中,这会产生输出...

<html>
  <table border="1">
    <thead>
      <tr>
        <td>Name</td>
        <td>Total</td>
      </tr>
    </thead>
    <tr>
      <td>troy madison</td>
      <td>26589</td>
    </tr>
    <tr>
      <td>Morris</td>
      <td>635</td>
    </tr>
  </table>
</html>
于 2012-09-09T14:15:53.740 回答