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?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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
Gertone (Geert Bormans)Information 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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
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
Rowby Goren Makes an Impact on Screen and Online

Learn about longtime user Rowby Goren and his great contributions to the site. We explore his method for posing questions that are likely to yield a solution, and take a look at how his career transformed from a Hollywood writer to a website entrepreneur.

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
Gertone (Geert Bormans)Information 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
Gertone (Geert Bormans)Information ArchitectCommented:
welcome
0
Gertone (Geert Bormans)Information 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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
XML

From novice to tech pro — start learning today.