3

I would like to list all collections from a particular point recursively:

declare function local:list-collections($collection as xs:string) {
    for $child in xmldb:get-child-collections($collection)
    return
        local:list-collections(concat($collection, '/', $child))
};

local:list-collections('/db/apps/tested-bunny/data/')

This returns nothing (no errors, no results). I am inspired by this article and consider it as a good starting point for recursive setting of permissions and so on.

Joe Wicentowski
  • 5,159
  • 16
  • 26
Honza Hejzl
  • 874
  • 8
  • 23

2 Answers2

4

See the dbutil:scan-*() functions in Wolfgang Meier's article on higher order functions with XQuery in eXist-db 2.0+. The article is very instructive article in general. These days the dbutil module is available in the shared-resources package that is installed by default with eXist, so you can make use of it as follows:

xquery version "3.0";

import module namespace dbutil="http://exist-db.org/xquery/dbutil" 
    at "/db/apps/shared-resources/content/dbutils.xql";

dbutil:scan-collections(
    xs:anyURI('/db'), 
    function($collection) { $collection } 
)

These functions perform well. I just ran this in eXide and the query returned 4125 collection names in 0.699s.

Joe Wicentowski
  • 5,159
  • 16
  • 26
  • 1
    Thank you for your answer, I forgot about it. The use of HoF is however quite advanced in xquery, it might be a bit too complex. – DiZzZz Apr 29 '16 at 21:57
4

Your query does actually recursively find collections, but there is no output. I'd suggest to do something like

declare function local:list-collections($collection as xs:string) {

    for $child in xmldb:get-child-collections($collection)
    let $childCollection := concat($collection, '/', $child)
    return
        (local:list-collections($childCollection), $childCollection)
};

local:list-collections('/db/apps/fundocs')

But for sure Joe's suggestion is much cleaner.

DiZzZz
  • 621
  • 3
  • 12
  • Thanks, actually, I like both solutions! The Joe's one is probably more elegant but I need to understand what is going on in it. This one is based on more humble logic and for me it is clear. – Honza Hejzl May 01 '16 at 17:55
  • Just a note: I don’t know why but it seems this function actually does not list everything in the tree. It seems it returns only some deeper branches. It is quite hard to test that thoroughly in eXide (it allows me to return only 10 items). – Honza Hejzl May 02 '16 at 08:23
  • Actually, this one returns 14 items, the other 31 items (which seems to be true). There is some glitch in this one. It seems it stops listing the current parent collection if there **are** children. – Honza Hejzl May 02 '16 at 08:36
  • It is interesting, this one function returns always 1 item less then the scanning one :) I don’t know which one item, guess it could be the root collection. – Honza Hejzl May 03 '16 at 07:07