Search

Hey XSLT wizards, here’s a question. Say I have lots of XML entries that look like this:

<entry>
  <foo>1</foo>
  <bar>3</bar>
</entry>

I want to get a list of the distinct <foo> values (0-n), and then I want the sum of all values of <bar> for each entry where <foo> equals n.

I think I’m close using EXSLT set:distinct like this:

<xsl:for-each select="set:distinct(/entry/foo)">
   <xsl:value-of select="sum(/entry[foo=current()]/bar)" />
</xsl:for-each>

but this doesn’t work.

Any other ideas? Am I overthinking this? Maybe there is an easier way…

@jonasd - It doesn’t look like libxslt supports set:distinct().

@jonasd - It doesn’t look like libxslt supports set:distinct().

I haven’t played with EXSLT:functions yet, but you could try to implement it yourself using this template.

I don’t think you need set:distinct. Something like this should work (untested):

<xsl:for-each select="/entry[not(foo = preceding-sibling::entry/foo)]/foo">
    <xsl:value-of select="sum(/entry[foo = current()]/bar)" />
</xsl:for-each>

Basically use the preceding-sibling axis to only select the first occurrence of a value in .

You guys are awesome. I finally got it sorted out; it took a bit of tweaking because my XML is quite a bit more complex than the example I gave, but @froded’s approach was the ticket.

Glad to hear it helped you :) Only now I see <foo> didn’t get escaped in my last sentence…

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details