使用 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 := " ";
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>
我想将来自一个大 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 := " ";
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>