I have created a XSLT file that can transform a single XML file. However, I have several hundred directories with multiple xml files. Is there a way in XSLT to transform all the
Here is probably the simplest example how to process all the xml files in a file system subtree (using the collection()
function as implemented in Saxon):
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*" mode="inFile">
<xsl:copy>
<xsl:apply-templates mode="inFile" select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates mode="inFile" select=
"collection('file:///C:/temp?select=*.xml;recurse=yes')"/>
</xsl:template>
</xsl:stylesheet>
When applied on any XML document (not used, ignored), this transformation applies the identity rule to every XML document contained in any of the *.xml
files in the C:/Temp
subtree of the file system.
To do more neaningful processing, one needs to override the identity template -- in the inFile
mode.
In your specific case I believe you can simply replace:
<xsl:apply-templates select="/testResults/result/tables/table[14]">
with
<xsl:apply-templates select="./testResults/result/tables/table[14]">
and this applies the desired templates on the nodes selected off the current (document) node.
I just wanted to add a lightweight version of Dimitre's excellent answer. If you have <foo>
documents (root node) sitting in a directory, and a working XSLT program for <foo>
, simply make your top-level template like this:
<xsl:template match="/">
<xsl:apply-templates select="collection($my_url)/foo"/>
</xsl:template>
That's assuming you want the URL as a parameter, <xsl:param name="my_url"/>
, specified on the command line.