Brendan,
This was a fun problem so I looked at it last night.
Here's my solution. It uses the EXSL node-set extension function. I tried
to think about how to do it without, but it made my brain hurt. That is not
to say that it can't be done. (Actually now I see Josh may have done that. :-)
To use exslt:node-set() in this way is, in effect, to run more than one
pass over the document. Rather than taking the flat linked structure and
making a true hierarchy to traverse, however, this approach is to traverse
the virtual hierarchy and collect the data points as it goes into a uniform
flat structure with no links and no implicit hierarchy, then go from there.
Basically the key is used to retrieve folders recursively from one another,
traversing the hierarchy. The count of files in each is then written to a
result-tree; the stylesheet simply sums the files from the result tree
(converted into a node set using the extension function) and reports the sum.
<xsl:stylesheet version="1.0"
xmlns:exslt="http://exslt.org/common"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:param name="start" select="'dir0'"/>
<xsl:key name="folder-by-id" match="folder" use="@id"/>
<xsl:variable name="collected">
<xsl:apply-templates select="key('folder-by-id',$start)" mode="collect"/>
</xsl:variable>
<xsl:template match="folder" mode="collect">
<files>
<xsl:value-of select="@files"/>
</files>
<xsl:apply-templates select="key('folder-by-id',file/@id)" mode="collect"/>
</xsl:template>
<xsl:template match="/">
<xsl:value-of select="sum(exslt:node-set($collected)/files)"/>
</xsl:template>
</xsl:stylesheet>
You can pass a parameter in to designate which folder you want to get the
count of. There does have to be one folder at the "top" of your count
(though this starting folder can be anywhere).
Note it should be really easy to write an instance document that would send
your processor into orbit using this stylesheet -- all you need to do is
have a folder "contain" itself at some level. Different processors have
different ways of handling infinite loops.
Cheers,
Wendell
At 07:46 PM 1/14/2004, you wrote:
Perhaps the way to go is to write an xslt to convert from the flat file
format to a nested one.
======================================================================
Wendell Piez
mailto:wapiez(_at_)mulberrytech(_dot_)com
Mulberry Technologies, Inc. http://www.mulberrytech.com
17 West Jefferson Street Direct Phone: 301/315-9635
Suite 207 Phone: 301/315-9631
Rockville, MD 20850 Fax: 301/315-8285
----------------------------------------------------------------------
Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list