使用 SAXON/XQuery 编写输出文件

Writing output files with SAXON / XQuery

我想将来自一个大 XML 的一些 xml 片段保存到单独的文件中。来源 XML 如下所示:

<files>
  <file name="foo.xml">
    <data>...</data>
    Something
  </file>
  ...
  <file name="bar.xml">
    Something else
  </file>
</files>

据我所知,XQuery 中没有标准的结果文档函数(只有 saxon/user 扩展)。但是我们有fn:transform,它可以执行有<xsl:result-document>的XSLT,所以我写了下面的代码:

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)

问题是,实际上没有写入任何文件(也没有错误消息)。为了简化它,我在脚本中使用了绝对路径“F:\z.txt”(它应该使用 $path)。知道有什么问题吗?如果我在没有 XQuery(纯 XSLT)的情况下做同样的事情,它似乎可以工作。

(我使用“Saxon-HE 9.9.1.7J”)

如果没有扩展函数似乎是不可能的,因此我只是切换到纯 XSLT 解决方案(但我更喜欢 XQuery):

这是样式表:

<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>