0

現在、XSLT 内で NaN エラーが発生しています。注文したすべての製品とその数量の合計値または収益を取得したいと考えています。

XML:

<customers>
<customer>
<customername>John</customername>
</customer>
<invoices>
 <invoice>
  <invoicenumber>01</invoicenumber>
  <products>
   <product>
    <productname>candy bar</productname>
    <productamount>6</productamount
    <productcost>2</productcost>
   </product>
  </products>
 </invoice>
 <invoice>
  <invoicenumber>02</invoicenumber>
  <products>
   <product>
    <productname>choco bar</productname>
    <productamount>3</productamount
    <productcost>1</productcost>
   </product>
  </products>
 </invoice>
</invoices>
<customer>
<customername>Fritz</customername>
</customer>
<invoices>
 <invoice>
  <invoicenumber>01</invoicenumber>
  <products>
   <product>
    <productname>Soda</productname>
    <productamount>3</productamount
    <productcost>2</productcost>
   </product>
  </products>
 </invoice>
 <invoice>
  <invoicenumber>02</invoicenumber>
  <products>
   <product>
    <productname>lollipop</productname>
    <productamount>5</productamount
    <productcost>1</productcost>
   </product>
  </products>
 </invoice>
</invoices>

そして、再帰テンプレートを適応させようとしました。

XSL:

Total:  
<xsl:call-template name="sumProducts">
<xsl:with-param name="pNodes" select="customers/customer/invoices/invoice/products"/>
<xsl:with-param name="pName1" select="././././././productamount"/>
<xsl:with-param name="pName2" select="././././././productcost"/>
</xsl:call-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>

望ましい結果は、合計 = 26 になります。

4

2 に答える 2

2

あなたの XSLT にはいくつか問題があります。まず、pNodesパラメータの設定が正しくありません

<xsl:with-param name="pNodes" select="customers/customer/invoices/invoice/products"/>

XML を見ると、次のようにする必要があります。

<xsl:with-param name="pNodes" select="customers/invoices/invoice/products/product"/>

つまり、請求書要素はサンプルの顧客要素内になく、さらに個々の製品要素を合計したいと考えています。

次に、Ian Roberts が述べたように、pName1pName2は要素名に設定する必要があるように見えます。現在、それらの要素の最初の出現の値にそれらを設定しているだけです。

<xsl:with-param name="pName1" select="'productamount'"/>
<xsl:with-param name="pName2" select="'productcost'"/> 

最後に、pAccumパラメータの設定が間違っています。あなたは現在これをやっています...

<xsl:with-param name="pAccum" 
   select="$pAccum + $pNodes[1]/*[name()=$pName1] * pNodes[1]/*[name()=$pName2]"/> 

しかし、2 番目のpNodes変数の前に $ がありません。これは次のようになります。

<xsl:with-param name="pAccum" 
   select="$pAccum + $pNodes[1]/*[name()=$pName1] * $pNodes[1]/*[name()=$pName2]"/> 

これが完全な XSLT で、26 を与えるはずです。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>
   <xsl:template match="/">
      <xsl:call-template name="sumProducts">
         <xsl:with-param name="pNodes" select="customers/invoices/invoice/products/product"/>
         <xsl:with-param name="pName1" select="'productamount'"/>
         <xsl:with-param name="pName2" select="'productcost'"/>
      </xsl:call-template>
   </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() &gt; 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>
于 2012-10-22T12:09:33.113 に答える
0

再帰テンプレートは問題ないように見えますが、問題は初期値pName1pName2パラメーター値にあると思います。試す

<xsl:with-param name="pName1" select="'productamount'"/>
<xsl:with-param name="pName2" select="'productcost'"/>

テンプレートは、これらのパラメーターが関連する要素の名前selectを含む文字列であることを想定しています。そのため、二重引用符で囲まれた属性内に単一引用符が必要です。

于 2012-10-22T11:49:00.267 に答える