Writing output files with SAXON / XQuery
I’d like to save some xml fragments from one big XML into individual files. The source XML looks like this:
<files> <file name="foo.xml"> <data>...</data> Something </file> ... <file name="bar.xml"> Something else </file> </files>
As far as I know there is no standard result-document function in XQuery (just saxon/user extensions). But we have fn:transform
, which can execute XSLT which has <xsl:result-document>
, so I wrote the following code:
declare namespace map = "http://www.w3.org/2005/xpath-functions/map"; declare option saxon:output "method=xml"; declare option saxon:output "indent=yes"; declare variable $nl := " "; declare variable $input as item() external; declare function local:saveFile($path, $content) { let $stylesheet := document{ <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> <xsl:template match="/"> <xsl:result-document href="file:///F:/z.txt" method="xml"> <xsl:copy-of select="."/> </xsl:result-document> <success>Created file: {$path}</success> </xsl:template> </xsl:stylesheet> } let $transFormResultMap := fn:transform( map{ "stylesheet-node": $stylesheet ,"source-node": document { $content } } ) return $transFormResultMap ? output }; for $file in $input/files/file let $fileName := fn:string(( $file/@name, $file/@NAME )[1]) let $content := $file/* return local:saveFile($fileName, $content)
The problem is, that no file are written actually (and no error message). To simplify it I use the absolute path "F:\z.txt" in the script (it should use $path). Any idea what is wrong? If I do the same without XQuery (pure XSLT) it seems to work.
(I use "Saxon-HE 9.9.1.7J")
It seems to be not really possible without extension-functions, therefore I just switched to the pure XSLT-solution (but I prefer XQuery):
This is the stylesheet:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> <xsl:param name="dir"></xsl:param> <xsl:template match="/files/file"> <xsl:variable name="filename" select="./@name" /> <xsl:result-document href="{$dir}{$filename}" method="xml"> <xsl:copy-of select="./*"/> </xsl:result-document> <success>Created file: <xsl:value-of select="$filename" /></success> </xsl:template> </xsl:stylesheet>