xsl-list
[Top] [All Lists]

RE: recursive addition

2004-01-14 18:08:18
It sounds to me like what you want is this: 
Given dir1 you want to add 4 from the files attribute of 
folder[(_at_)id='dir1'] , plus 3 from the files attribute from 
folder[(_at_)id='dir2'], plus the 6 from the files attribute of 
folder[(_at_)id='dir3'] for a total of 13.

I believe the following xslt should fit your needs. It could probably be 
simplified, but I was just banging it out...

I've learned to love <xsl:message> while writing this, excellent for dumping 
out what's going on...

Josh

<?xml version="1.0"?>

<xsl:stylesheet 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
  version="1.0">
<xsl:output method="xml" indent="yes" xmlns:xalan="http://xml.apache.org/xslt";
  xalan:indent-amount="2"/>

<xsl:template match="/root">
  <!-- the id of the folder to count -->
  <xsl:variable name="dir-id" select="'dir1'"/>

  <xsl:variable name="count">
    <xsl:call-template name="count-files">
      <xsl:with-param name="dir" select="/root/folder[(_at_)id=$dir-id]"/>
    </xsl:call-template>
  </xsl:variable>

  There are <xsl:value-of select="$count"/> files under <xsl:value-of 
select="$dir"/>.

</xsl:template>

<xsl:template name="count-files">
  <xsl:param name="dir"/>

  <!-- count the files in this dir -->
  <xsl:variable name="counter">
    <xsl:choose>
      <xsl:when test="$dir/file[(_at_)id]">
        <xsl:call-template name="count-subfiles">
          <xsl:with-param name="file" select="$dir/file[(_at_)id][1]"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>0</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:value-of select="$dir/@files + $counter"/>

</xsl:template>

<xsl:template name="count-subfiles">
  <xsl:param name="file"/>

  <!-- count the files in the related dir -->
  <xsl:variable name="x">
    <xsl:call-template name="count-files">
      <xsl:with-param name="dir" select="/root/folder[(_at_)id=$file/@id]"/>
    </xsl:call-template>
  </xsl:variable>

  <!-- count the files in the following-sibling files with dir ids-->
  <xsl:variable name="y">
    <xsl:choose>
      <xsl:when test="$file/following-sibling::file[(_at_)id]">
        <xsl:call-template name="count-subfiles">
          <xsl:with-param name="file" 
select="$file/following-sibling::file[(_at_)id][1]"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>0</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:value-of select="$x + $y"/>

</xsl:template>

</xsl:stylesheet>

-----Original Message-----
From: annirack(_at_)shaw(_dot_)ca [mailto:annirack(_at_)shaw(_dot_)ca]
Sent: Wednesday, January 14, 2004 2:42 PM
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
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.

Sorry, I guess the example was a little unclear.  I want to sum the files 
attribute for *all* folders under the initial parent.  So the result I'd want 
from dir0 would be 25.  The sum of the file attributes of all the folder 
elements is 27. 

Is that a little clearer?

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)?

All branches and leaves, but not the trunk. (where an arbitrary starting point 
is the trunk)

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>



 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>