After having transformed my large xml files into a series of paginated html fragments, for crossreferences I am now working on an xsl function that needs to know which file a certain node (resp. the element it has been transformed to) has ended up in.
The files are named like this: 001_div1.html
, 002_div2.html
etc. Suppose I know that I want the _div25.html
, but I don't know the number prefix. As I understand it, xpath's collection()
function would help me out, but it doesn't.
I assume this is due to the eXist-launched saxon not being aware that we're dealing with nodes in an xml database, not files in the filesystem. But then again, with doc('../../html/003_div3.html')
it does work as it does with document-available('../../html/003_div3.html')
, so these functions are somehow fed with nodes from the db...
What I would like to do is this:
<xsl:for-each select="collection('../../html/*_div25.html')">
<xsl:value-of select="tokenize(replace(document-uri(.), '.html$', ''),'/')[last()]"/>
</xsl:for-each>
But this gives me:
Exception while transforming node: Exception thrown by URIResolver
Here is the hack I am presently using:
<xsl:for-each select="1 to $maxNumberOfHtmlFragments"> <!-- For all those numbers, check if there is a filename
starting with the number, followed by the known NodeId,
and ending with .html. -->
<xsl:variable name="filename" select="concat('../../html/', xs:string(format-number(position(), '000')), '_div25.html')"/>
<xsl:if test="doc-available($filename)">
<xsl:value-of select="tokenize(replace($filename, '.html$', ''),'/')[last()]"/>
</xsl:if>
</xsl:for-each>
But this has quite some performance impact! Note that using the same paths (without wildcards of course) in document()
and doc-available()
does work fine.
Is the eXist-saxon connection lacking with regard to the collection() function?
Are there better ways of achieving what I want anyway?