简体   繁体   中英

add multiple nodes in for-each loop in xslt 1.0

Here is my xml

<TAG>
<PAYMENT name="delhi">       PAY10 <PAYMENT>
<PAYMENT name="mumbai">      PAY20 <PAYMENT>
<PAYMENT name="singapore">   PAY30 <PAYMENT>
<PAYMENT name="tokyo">       PAY40 <PAYMENT>
<PAYMENT name="new york">    PAY50 <PAYMENT>
<PAYMENT name="london">      PAY60 <PAYMENT>
</TAG>

requirement is to add all the PAYMENT tag value for delhi/mumbai cities. eg. Expected output = 30 ( 10 + 20 = 30) [ after trimming PAY ]

xslt(1.0) :

<xsl:variable name="amt_delhi">
   <xsl:if test="contains(.,"TAG/PAYMENT[name='delhi'])">
     <xsl:value-of select="substring-after('TAG/PAYMENT[name='delhi')',4)"/>
   </xsl:if>
</xsl:variable>
<xsl:variable name="amt_mumbai">
  <xsl:if test="contains(.,"TAG/PAYMENT[name='mumbai'])">
      <xsl:value-of select="substring-after('TAG/PAYMENT[name='mumbai')',4)"/>
  </xsl:if>
</xsl:variable>

<xsl:variable name="total_amt">
    <xsl:value-of select="$amt_delhi + $amt_mumbai"/> 
</xsl:variable>
<xsl:message><xsl:value-of select="$total_amt"/></xsl:message>

My question is currently I have 100 more such fields and it is difficult to manage xslt whenever new change comes. Is there any better way to achieve it? (eg. for-each loop) to minimize the number of line of code in xslt.

How about:

XSLT 1.0 (+EXSLT node-set function)

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:template match="/TAG">
    <!-- pre-process -->
    <xsl:variable name="delhi_mumbai_amounts">
        <xsl:for-each select="PAYMENT[@name='delhi' or @name='mumbai']">
            <amount>
                <xsl:value-of select="substring-after(., 'PAY')"/>
            </amount>   
        </xsl:for-each>
    </xsl:variable>
    <!-- output -->
    <output>
        <xsl:value-of select="sum(exsl:node-set($delhi_mumbai_amounts)/amount)"/>
    </output>
</xsl:template>

</xsl:stylesheet>

This is assuming there can be more than one occurrence of PAYMENT with the same name. Otherwise you could do simply:

<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:template match="/TAG">
    <output>
        <xsl:value-of select="substring-after(PAYMENT[@name='delhi'], 'PAY') +substring-after(PAYMENT[@name='mumbai'], 'PAY')"/>
    </output>
</xsl:template>

</xsl:stylesheet>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM