xsl-list
[Top] [All Lists]

Re: recursive addition

2004-01-14 15:33:56
The semantics are most definitely unclear but im assuming that you know what
you want to gain out of adding dir2 and dir3.  With this in mind the
following XSLT will give you what you want...

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:root="http://root"; version="1.0">

<xsl:template match="/">
 <xsl:value-of select="sum(root/folder[(_at_)id = 'dir2' or @id =
'dir3']/@files)"/>
</xsl:template>

</xsl:stylesheet>

If you find you need to recursively move through your XML (and I am assuming
you will given the nature of a filesystem) and find all folder elements you
would use the double slash between root and folder, like so:

 <xsl:value-of select="sum(root//folder[(_at_)id = 'dir2' or @id =
'dir3']/@files)"/>

You could even remove root and just have //folder... but in this case it
doesnt matter as the result is the same. // simply recursively pulls all
folder elements that occur after the current context node, in this case the
root of the xml tree ( you got there buy putting / in the template match
attribute ), no matter where they fall in the XML document order.

Best regards,

M.

----- Original Message ----- 
From: "Lars Huttar" <lars_huttar(_at_)sil(_dot_)org>
To: <xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com>
Sent: Wednesday, January 14, 2004 3:08 PM
Subject: RE: [xsl] recursive addition


One question -- what does the attribute @files mean on
the folder element whose @id="dir1"? It has @files="4",
but that doesn't seem to enter into the calculation you're
doing. So the semantics of the XML are a little unclear to me.

-----Original Message-----
From: owner-xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
[mailto:owner-xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com]On Behalf Of
annirack(_at_)shaw(_dot_)ca
Sent: Wednesday, January 14, 2004 2:41 PM
To: XSL-List(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: [xsl] recursive addition


I have a structure (much like a file system) where elements
of the same type are linked together via IDs rather than the
XML structure--i.e. all directory elements are at the same level.

For an arbitrary directory level element, I want to sum a
numeric attribute for all linked elements and so on down the tree.

To rephrase the above question, are you just summing the attributes
of leaf folders (as you appear to be in your example where you
expect the answer to be 9)?

Is there any way to do this?  I know that recursion is the
first step, but what I don't know how to sum an arbitrary
number of parallel level attributes in different elements.

Here's an example:
<root>
   <folder files="2" id="dir0">
      <file id="dir1" />

      <file id="dir4" />
   </folder>

   <folder files="4" id="dir1">
      <file id="dir2" />

      <file id="dir3" />
   </folder>

   <folder files="3" id="dir2" />

   <folder files="6" id="dir3" />

   <folder files="7" id="dir4" />

   <folder files="5" id="dir5" />
</root>

If my arbitrary element id is "dir1", then the result should
be 9. (folder[(_at_)id='dir2']/@files + folder[(_at_)id='dir3']/@files)

How do I do that with xsl?

Assuming you're only summing the @files attributes of folders
that have no subfolders, here's some pseudo code:

with parameter folderID

main template
  variable folder = /root/folder[(_at_)id = $folderID]
  call template sumFiles(folder, 1)

template name=sumFiles
  params folder, startFrom

  if not(child::file) return @files
  else if not(child::file[startFrom]) return "0"
  else {
    variable firstChild = child::file[startFrom]
    firstSum = sumFiles(/root/folder[(_at_)id = $firstChild/@id], 1)
    restSum = sumFiles(., startFrom+1)
    return xsl:value-of select="$firstSum + $restSum";
  }

Does that help?

Of course you could make it more efficient by using keys/id's.

You could probably also make the code simpler by using an extension
function to build a nodeset and then use sum() on it.

Lars


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



<Prev in Thread] Current Thread [Next in Thread>