eXist-db compression:zip 函数是否添加 XML 声明
Does eXist-db compression:zip function add XML declaration
我有一个 XQuery 函数可以将一组 XML 文件转换为 HTML 并压缩它们。它 运行 对每个文件进行转换以创建 元素。
从那个函数开始:
declare function xport:make-sources( $path as xs:string) as item()* {
for $article in collection(xmldb:encode-uri($path))
let $docnum := $article/article/div[@class = 'content']/@doc/string()
return
<entry name="{concat($docnum,'.html')}" type='text' method='store'>
{transform:transform($article, doc("/db/EIDO/data/edit/xsl/doc-html.xsl"), <parameters/>)}
</entry>
} ;
根据输入,我 运行 XQuery 只显示转换结果...我看到了这个(正是我所期望的):
<entry name="LS01.html" type="text" method="store">
<html>
<head>
<style>
body {
font-family: Arial;
}
article img {
width:50%;
}
...
你会注意到这个条目,它们都没有 XML 声明。
但现在让我们将它们放在一起并将这些条目发送到压缩。这一切都在 Web 应用程序中。完整的 XQuery 是这样的:
xquery version "3.0";
import module namespace transform = "http://exist-db.org/xquery/transform";
declare namespace xport = "http://www.xportability.com";
declare function xport:make-sources( $path as xs:string) as item()* {
for $article in collection(xmldb:encode-uri($path))
let $docnum := $article/article/div[@class = 'content']/@doc/string()
return
<entry name="{concat($docnum,'.html')}" type='text' method='store'>
{transform:transform($article, doc("/db/EIDO/data/edit/xsl/doc-html.xsl"), <parameters/>)}
</entry>
} ;
let $path := request:get-parameter("path", "")
let $filename := request:get-parameter("filename", "")
let $col := xport:make-sources($path)
return
response:stream-binary(
xs:base64Binary(compression:zip($col,true()) ),
'application/zip',
$filename
)
一切正常,我得到了一个 ZIP 文件,其中包含已从 XML 转换为 HTML 的所有文档。
但是,当我查看 ZIP 中的实际文件时,它具有以下内容:
<?xml version="1.0" encoding="UTF-8"?>
<html>
<head>
XML 声明不在 ZIP 的任何条目上。它不存在于条目列表中的任何地方(因为它不可能存在)。但是压缩它们的动作显然是在添加声明。我看不出其他原因或方式。即使指定省略-xml-声明或将 XSL 中的输出类型更改为文本或 HTML 也没有任何区别。这是当然的,因为 zip 的条目列表如上所示,这表明声明在 转换后 不存在。
ZIP 中的文件添加了 XML 声明,句点。
有什么解决方法吗?
当 zip-bound <entry>
元素的内容传递给 compression:zip()
函数时,XML 声明在您的查询中隐式引入。我建议使用 fn:serialize()
函数显式设置序列化选项。以下示例代码展示了如何实现您描述的结果:
xquery version "3.1";
let $node := <html><head/><body><div><h1>Hello World!</h1></div></body></html>
let $serialized := serialize($node, map { "method": "xml", "indent": true(),
"omit-xml-declaration": true() })
let $entries := <entry name="test.html" type="text" method="store">{$serialized}</entry>
let $filename := "test.zip"
return
response:stream-binary(
compression:zip($entries, true()),
'application/zip',
$filename
)
将此查询保存到数据库中类似 /db/apps/my-app/test.xq
的位置并通过将您的 Web 浏览器指向 http://localhost:8080/exist/apps/my-app/test.xq 来调用它会导致您的浏览器下载 test.zip
。打开此 zip 文件将显示缺少 XML 声明的 test.html
文件:
<html>
<head/>
<body>
<div>
<h1>Hello World!</h1>
</div>
</body>
</html>
回到基础,XQuery 中是否存在 XML 声明是通过 omit-xml-declaration
serialization parameter 切换的。要为整个查询全局省略 XML 声明,您可以将这组声明放在查询的序言中:
declare namespace output="http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method "xml";
declare option output:omit-xml-declaration "yes";
或者,当在查询的一部分中进行本地序列化时,您可以将同一组参数作为映射传递给 fn:serialize
函数(上面代码示例中使用的方法):
fn:serialize($node, map { "method": "xml", "omit-xml-declaration": true() } )
(第二个选项参数也有一个 XML 语法。)
当前版本的 eXist (v4.0.0) 和最新版本(可能自 v3.6.0 左右)支持上述所有选项,并且所有版本都支持更紧凑的 eXist-specific serialization facility,使用exist:serialize
选项表示为由 key=value
对组成的字符串:
declare option exist:serialize "method=xml omit-xml-declaration=yes";
您可以在 conf.xml configuration file. The defaults in conf.xml can be overridden with the methods above. Serialization behavior over different interfaces in eXist, such as WebDAV or XML-RPC, typically respect the defaults set in conf.xml, but these defaults can be overridden on a per-interface basis; for example, see the documentation on serialization over eXist's WebDAV interface.
中设置 eXist 的默认序列化行为
我有一个 XQuery 函数可以将一组 XML 文件转换为 HTML 并压缩它们。它 运行 对每个文件进行转换以创建
从那个函数开始:
declare function xport:make-sources( $path as xs:string) as item()* {
for $article in collection(xmldb:encode-uri($path))
let $docnum := $article/article/div[@class = 'content']/@doc/string()
return
<entry name="{concat($docnum,'.html')}" type='text' method='store'>
{transform:transform($article, doc("/db/EIDO/data/edit/xsl/doc-html.xsl"), <parameters/>)}
</entry>
} ;
根据输入,我 运行 XQuery 只显示转换结果...我看到了这个(正是我所期望的):
<entry name="LS01.html" type="text" method="store">
<html>
<head>
<style>
body {
font-family: Arial;
}
article img {
width:50%;
}
...
你会注意到这个条目,它们都没有 XML 声明。
但现在让我们将它们放在一起并将这些条目发送到压缩。这一切都在 Web 应用程序中。完整的 XQuery 是这样的:
xquery version "3.0";
import module namespace transform = "http://exist-db.org/xquery/transform";
declare namespace xport = "http://www.xportability.com";
declare function xport:make-sources( $path as xs:string) as item()* {
for $article in collection(xmldb:encode-uri($path))
let $docnum := $article/article/div[@class = 'content']/@doc/string()
return
<entry name="{concat($docnum,'.html')}" type='text' method='store'>
{transform:transform($article, doc("/db/EIDO/data/edit/xsl/doc-html.xsl"), <parameters/>)}
</entry>
} ;
let $path := request:get-parameter("path", "")
let $filename := request:get-parameter("filename", "")
let $col := xport:make-sources($path)
return
response:stream-binary(
xs:base64Binary(compression:zip($col,true()) ),
'application/zip',
$filename
)
一切正常,我得到了一个 ZIP 文件,其中包含已从 XML 转换为 HTML 的所有文档。
但是,当我查看 ZIP 中的实际文件时,它具有以下内容:
<?xml version="1.0" encoding="UTF-8"?>
<html>
<head>
XML 声明不在 ZIP 的任何条目上。它不存在于条目列表中的任何地方(因为它不可能存在)。但是压缩它们的动作显然是在添加声明。我看不出其他原因或方式。即使指定省略-xml-声明或将 XSL 中的输出类型更改为文本或 HTML 也没有任何区别。这是当然的,因为 zip 的条目列表如上所示,这表明声明在 转换后 不存在。
ZIP 中的文件添加了 XML 声明,句点。
有什么解决方法吗?
当 zip-bound <entry>
元素的内容传递给 compression:zip()
函数时,XML 声明在您的查询中隐式引入。我建议使用 fn:serialize()
函数显式设置序列化选项。以下示例代码展示了如何实现您描述的结果:
xquery version "3.1";
let $node := <html><head/><body><div><h1>Hello World!</h1></div></body></html>
let $serialized := serialize($node, map { "method": "xml", "indent": true(),
"omit-xml-declaration": true() })
let $entries := <entry name="test.html" type="text" method="store">{$serialized}</entry>
let $filename := "test.zip"
return
response:stream-binary(
compression:zip($entries, true()),
'application/zip',
$filename
)
将此查询保存到数据库中类似 /db/apps/my-app/test.xq
的位置并通过将您的 Web 浏览器指向 http://localhost:8080/exist/apps/my-app/test.xq 来调用它会导致您的浏览器下载 test.zip
。打开此 zip 文件将显示缺少 XML 声明的 test.html
文件:
<html>
<head/>
<body>
<div>
<h1>Hello World!</h1>
</div>
</body>
</html>
回到基础,XQuery 中是否存在 XML 声明是通过 omit-xml-declaration
serialization parameter 切换的。要为整个查询全局省略 XML 声明,您可以将这组声明放在查询的序言中:
declare namespace output="http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method "xml";
declare option output:omit-xml-declaration "yes";
或者,当在查询的一部分中进行本地序列化时,您可以将同一组参数作为映射传递给 fn:serialize
函数(上面代码示例中使用的方法):
fn:serialize($node, map { "method": "xml", "omit-xml-declaration": true() } )
(第二个选项参数也有一个 XML 语法。)
当前版本的 eXist (v4.0.0) 和最新版本(可能自 v3.6.0 左右)支持上述所有选项,并且所有版本都支持更紧凑的 eXist-specific serialization facility,使用exist:serialize
选项表示为由 key=value
对组成的字符串:
declare option exist:serialize "method=xml omit-xml-declaration=yes";
您可以在 conf.xml configuration file. The defaults in conf.xml can be overridden with the methods above. Serialization behavior over different interfaces in eXist, such as WebDAV or XML-RPC, typically respect the defaults set in conf.xml, but these defaults can be overridden on a per-interface basis; for example, see the documentation on serialization over eXist's WebDAV interface.
中设置 eXist 的默认序列化行为