简体   繁体   中英

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 := "&#10;";
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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM