XSLT Convert multiple files from a subdirectory

I created an XSLT file that can convert a single XML file. However, I have several hundred directories with several xml files. Is there a way in XSLT to convert all these files. I use the collection function to get a list of all files. But, not sure how to apply the conversion now.

Here is my example XSLT file. Basically, I want to view all the XML files and apply the template table to a single file. The result of all these transformations should be in one flat text file.

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:foo="http://whatever"> <xsl:output method="text" encoding="ISO-8859-1"/> <xsl:template name="process"> <xsl:variable name="files" select="collection('file:///C:/files/testResults?select=*.xml;recurse=yes')"/> <xsl:for-each select="$files"> <xsl:if test="(not(contains(document-uri(.), 'SuiteSetUp'))) and (not(contains(document-uri(.), 'SuiteTearDown')))"> <xsl:value-of select="tokenize(document-uri(.), '/')[last()]"></xsl:value-of> <xsl:apply-templates select="/testResults/result/tables/table[14]"> <xsl:with-param name="title" select="/testResults/rootPath"></xsl:with-param> </xsl:apply-templates> <xsl:apply-templates select="/testResults/result/tables/table[15]"/> </xsl:if> </xsl:for-each> </xsl:template> <xsl:template match="table"> <xsl:param name="testName"></xsl:param> <xsl:for-each select="row"> <xsl:if test="position() > 2"> <xsl:variable name="choices" select="col[2]"></xsl:variable> <xsl:if test="contains($choices, 'fail')"> <xsl:value-of select="$testName"></xsl:value-of> <xsl:text>|</xsl:text> <xsl:value-of select="col[1]"></xsl:value-of> <xsl:text>|</xsl:text> <xsl:value-of select="foo:getCorrectChoices(col[2])"></xsl:value-of> <xsl:text>|</xsl:text> <xsl:value-of select="foo:getExpectedChoices(col[2])"></xsl:value-of> <xsl:text>|</xsl:text> <xsl:call-template name="NewLine"/> </xsl:if> </xsl:if> </xsl:for-each> </xsl:template> <xsl:template name="NewLine"> <xsl:text>&#xA;</xsl:text> </xsl:template> <xsl:function name="foo:getCorrectChoices"> <xsl:param name="content"></xsl:param> <xsl:analyze-string select="$content" regex="\[(\[.+?\])\] fail"> <xsl:matching-substring> <xsl:value-of select="regex-group(1)"></xsl:value-of> </xsl:matching-substring> </xsl:analyze-string> </xsl:function> <xsl:function name="foo:getExpectedChoices"> <xsl:param name="content"></xsl:param> <xsl:analyze-string select="$content" regex="fail\(expected \[(\[.+?\])\]"> <xsl:matching-substring> <xsl:value-of select="regex-group(1)"></xsl:value-of> </xsl:matching-substring> </xsl:analyze-string> </xsl:function> </xsl:stylesheet> 
+7
source share
2 answers

Here is perhaps the simplest example of processing all xml files in a file system subtree (using the collection() function 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 to any XML document (not used, ignored), this transformation applies an identification rule to each XML document contained in any of the *.xml in the C:/Temp subtree of the file system.

To make more unnecessary processing, you need to redefine the authentication template - in inFile mode.

In your particular case, I believe that you can simply replace :

  <xsl:apply-templates select="/testResults/result/tables/table[14]"> 

from

  <xsl:apply-templates select="./testResults/result/tables/table[14]"> 

and this will apply the desired patterns on the nodes selected from the current (document) node.

+7
source

I just wanted to add a light version of Dimitre's excellent answer. If you have <foo> documents (root node) sitting in a directory and a working XSLT program for <foo> , just create a top-level template as follows:

 <xsl:template match="/"> <xsl:apply-templates select="collection($my_url)/foo"/> </xsl:template> 

Suppose you need a URL as parameter, <xsl:param name="my_url"/> , specified on the command line.

0
source

All Articles