Add value using XSL

Hi,

I need the XLS code to add the value of the boxes by type:
(I have more than 1000 records in the XML file )
<boxes>
<box>
      <id>1</id>
      <type>big</type>
      <value>1000</value>
</box>
<box>
      <id>2</id>
      <type>small</type>
      <value>200</value>
</box>
<box>
      <id>3</id>
      <type>small</type>
      <value>500</value>
</box>
</boxes>

Result
<box>
<big>1000</big>
<small>700</small>
</box>

Thank you,
Qw MAsked:
Who is Participating?
 
Geert BormansInformation ArchitectCommented:
In case there would be more types eg. 'medium', 'extra large'...
it could be nice to have a generic solution.

The following uses muenchian grouping, works perfect on your example, is not slower than zc2's solution but requires no hardcoding of the different types

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    
    <xsl:key name="box" match="box" use="normalize-space(type)"/>
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>
    
    <xsl:template match="boxes">
        <box>
            <xsl:apply-templates select="box[generate-id() = generate-id(key('box', normalize-space(type))[1])]"/>
        </box>
    </xsl:template>
    
    <xsl:template match="box">
        <xsl:element name="{normalize-space(type)}">
            <xsl:value-of select="sum(key('box', normalize-space(type))/value)"/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

Open in new window

0
 
zc2Commented:
If I understand your question correctly you need to calculate two sums, one for small boxes and another one for the big boxes?
Here's the stylesheet which does that:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="boxes">
    <box>
      <big><xsl:value-of select="sum(box[type='big']/value)"/></big>
      <small><xsl:value-of select="sum(box[type='small']/value)"/></small>
    </box>
  </xsl:template>
</xsl:stylesheet>

Open in new window

0
 
Qw MAuthor Commented:
Hi, thanks for your answer but I have another tag <output> that I've missed. Sorry for the mistake. Can you please help me?

<output>
<boxes>
<box>
      <id>1</id>
      <type>big</type>
      <value>1000</value>
</box>
<box>
      <id>2</id>
      <type>small</type>
      <value>200</value>
</box>
<box>
      <id>3</id>
      <type>small</type>
      <value>500</value>
</box>
</boxes>
</output>

Thank you,
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
zc2Commented:
If you don't need to put that <output> tag to the output XML, no changes is necessary.
The boxes template will be found from the default XSLT template which is just traverses all the tree looking for a suitable template to apply. If you need that tag be placed to the output as well, then there is a lot of way how to code that, here's one for an example:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

 <xsl:template match="output">
  <output>
   <xsl:apply-templates select="boxes"/>
  </output>
</xsl:template>

  <xsl:template match="boxes">
    <box>
      <big><xsl:value-of select="sum(box[type='big']/value)"/></big>
      <small><xsl:value-of select="sum(box[type='small']/value)"/></small>
    </box>
  </xsl:template>
</xsl:stylesheet>

Open in new window

0
 
Geert BormansInformation ArchitectCommented:
same applies to the solution I suggested.

if you don't need th eoutput element in the output, you don't have to change anything. If you need it in the output simply paste the template for output zc2 just did in the stylesheet I suggested earlier
0
 
Qw MAuthor Commented:
Thank you,
0
 
Geert BormansInformation ArchitectCommented:
welcome
0
 
Geert BormansInformation ArchitectCommented:
Hey, thanks for accepting my suggestion. Please note that zc2 provided a solution that actually works for this particular example and way before I posted mine. It is a common policy on Experts Exchange that you then show at least your appreciation for that by splitting points between his comment and mine. You don't necessarily have to select one solution, you can show appreciation for multiple solutions by the split points functionality. May I suggest that you take that approach next time around? Thanks
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.