XSLT2 collection() with dynamic collections from directory listings

Something I didn’t know about XSLT2’s collection() function. I had previously used it in the form:

<xsl:variable name="files" select="collection(docs.xml)"/>

where docs.xml has a structure of:

<?xml version="1.0"?>
<collection>
    <doc href="blort1.xml"/>
    <doc href="blort2.xml"/>
</collection>

You can then address, via the variable, the structure of those files blort1 and blort2 and iterate over them etc. e.g. you can do something like:

<xsl:for-each select="$files/tei:TEI/tei:text/tei:div">
  <xsl:apply-templates mode="TOC" select="tei:head"/>
</xsl:for-each>

Ok… I already knew how to do that and have used it to run XSLT on a whole raft of files. To get the docs.xml file I used to run “xmlstarlet ls” and then I have a dir2collection.xsl that transforms its output to the correct format.

However, what I didn’t know is that I didn’t need to bother creating the collection file at all. Saxon can generate the collection file from a parameter on the URI that you hand collection(). That is you can do something like:

<xsl:variable name="files" select="collection('../foo/?select=blor*.xml')"/>

And $files is then addressable in the same way as if you had made a collection document of all the files matching blor*.xml in the directory ../foo/ (and of course you can just do *.xml)

But wait, that’s not all. You can get a bit more complicated about it, pass the path as a parameter, and supply the collection() function extra parameters. So something like:

    <xsl:param name="path2collection">../foo/</xsl:param>
    <xsl:variable name="path">
        <xsl:value-of
            select="concat('../',$path2collection,'?select=*.xml;recurse=yes;on-error=warning')"
        />
    </xsl:variable>
    <xsl:variable name="docs" select="collection($path)"/>

And thus forth $docs contains a recursive collection of anything in the path2collection parameter you give it.

Isn’t that fun? Ok, maybe only me.

Posted in XML, XSLT | 1 Comment

One Response to “XSLT2 collection() with dynamic collections from directory listings”

  1. DOT says:

    This is exactly what I needed this morning. (Gosh, that sounds like spam, doesn’t it?)

    And I’m amused that I searched google for “XSLT collection()” and this blog post was the third of fourth hit :-)

Leave a Reply