在XSLT中使用foreach添加属性值

时间:2018-05-10 05:47:12

标签: xml xslt

下面是我的XSLT结构,我正在尝试为每个(EARNEDINCOMEAMOUNT * PAYMENTFREQUENCYTYPE)节点添加EARNEDINCOME

XSLT结构:

<EMPLOYMENT CUSTOMERNUMBER="1001349" CUSTOMERVERSIONNUMBER="31"  EMPLOYMENTSEQUENCENUMBER="2" EMPLOYMENTSTATUS="110" >  
  <EARNEDINCOME CUSTOMERNUMBER="1001349" CUSTOMERVERSIONNUMBER="31" EMPLOYMENTSEQUENCENUMBER="2" EARNEDINCOMESEQUENCENUMBER="1" EARNEDINCOMEAMOUNT="1142" PAYMENTFREQUENCYTYPE="12" PAYMENTFREQUENCYTYPE_TEXT="Monthly" />  
  <EARNEDINCOME CUSTOMERNUMBER="1001349" CUSTOMERVERSIONNUMBER="31" EMPLOYMENTSEQUENCENUMBER="2" EARNEDINCOMESEQUENCENUMBER="2" EARNEDINCOMEAMOUNT="4960" PAYMENTFREQUENCYTYPE="12" PAYMENTFREQUENCYTYPE_TEXT="Monthly" />
</EMPLOYMENT> 

到目前为止我所尝试的是。

<xsl:for-each select=".//EARNEDINCOME">
    <xsl:attribute name="GROSSINCOME">
    <xsl:value-of select="(EARNEDINCOME[@EMPLOYMENTSEQUENCENUMBER=$vSequenceNumber]/@EARNEDINCOMEAMOUNT * EARNEDINCOME[@EMPLOYMENTSEQUENCENUMBER=$vSequenceNumber]/@PAYMENTFREQUENCYTYPE)" />
    <xsl:value-of select="@EARNEDINCOMEAMOUNT*@PAYMENTFREQUENCYTYPE"/>
    </xsl:attribute>
</xsl:for-each>

从中获得的只是每个节点的乘法,但我无法添加它。请帮忙。

1 个答案:

答案 0 :(得分:1)

根据使用的XSLT版本,有不同的方法可以获得所需的总和。

XSLT 2.0 允许在sum()函数中使用XPath,因此下面的代码将提供所需的输出。

<xsl:template match="EMPLOYMENT">
    <SOMENODE>
        <xsl:attribute name="GROSSINCOME">
            <xsl:value-of select="sum(EARNEDINCOME/(@EARNEDINCOMEAMOUNT * @PAYMENTFREQUENCYTYPE))" />
        </xsl:attribute>
    </SOMENODE>
</xsl:template>

XSLT 1.0 并未提供实现此目的的简单方法。如果使用XSLT 1.0,您将编写一个递归模板调用,该调用将为每个节点执行产品,然后继续为所有节点添加它们。

<xsl:template match="EMPLOYMENT">
    <SOMENODE>
        <xsl:attribute name="GROSSINCOME">
            <xsl:call-template name="ProductSum">
                <xsl:with-param name="earnedIncome" select="*" />
            </xsl:call-template>
        </xsl:attribute>
    </SOMENODE>
</xsl:template>

<xsl:template name="ProductSum">
    <xsl:param name="earnedIncome" />
    <xsl:param name="sum" select="0" />

    <xsl:variable name="nodeStart" select="$earnedIncome[1]" />
    <xsl:variable name="nodeEnd" select="$earnedIncome[position() > 1]" />
    <xsl:variable name="currSum" select="$nodeStart/@EARNEDINCOMEAMOUNT * $nodeStart/@PAYMENTFREQUENCYTYPE" />
    <xsl:choose>
        <xsl:when test="not($nodeEnd)">
            <xsl:value-of select="$sum + $currSum" />
        </xsl:when>
        <xsl:otherwise>
            <!-- Recursive call to the same template -->
            <xsl:call-template name="ProductSum">
                <xsl:with-param name="earnedIncome" select="$nodeEnd" />
                <xsl:with-param name="sum" select="$sum + $currSum" />
            </xsl:call-template>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

使用 EXSLT(扩展功能) - 如果使用XSLT 1.0并且可以使用扩展功能,则可以使用node-set()功能。

<xsl:template match="/EMPLOYMENT">
    <!-- create a variable to store the EARNEDINCOME nodes along 
         with a new attribute ANNUALINCOME that has the product 
         of the attributes -->
    <xsl:variable name="nodes">
        <xsl:for-each select="EARNEDINCOME">
            <xsl:copy>
                <xsl:copy-of select="@*"/>
                <!-- add a new attribute to EARNEDINCOME node -->
                <xsl:attribute name="ANNUALINCOME">
                    <xsl:value-of select="@EARNEDINCOMEAMOUNT * @PAYMENTFREQUENCYTYPE" />
                </xsl:attribute>
            </xsl:copy>
        </xsl:for-each>
    </xsl:variable>
    <SOMENODE>
        <xsl:attribute name="GROSSINCOME">
            <!-- use the node-set function to compute the sum
                 of this new attribute from the above variable -->
            <xsl:value-of select="sum(exslt:node-set($nodes)/EARNEDINCOME/@ANNUALINCOME)" />
        </xsl:attribute>
    </SOMENODE>
</xsl:template>  

所有XSLT都将提供相同的输出

<SOMENODE GROSSINCOME="73224"/>