SaxonHE:如何在 XQuery 执行中使用 XSD 类型

SaxonHE: How to use XSD types on XQuery execution

我有以下 XML 文档:

<?xml version="1.0" encoding="UTF-8"?>
<root xsi:noNamespaceSchemaLocation="example.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <a>0.1</a>
    <b>0.2</b>
</root>

与以下 XSD 关联:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="a" type="xs:decimal"/>
                <xs:element name="b" type="xs:decimal"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

使用此代码片段我执行了一个 XQuery 表达式 let $a := /root/a, $b := /root/b, $res := $a + $b return $res:

var proc = new Processor(false);

var builder = proc.newDocumentBuilder();
builder.setBaseURI(URI.create("http://test.ru"));

var file = new File(filePath);
var doc = builder.build(file);

var expression = "let $a := /root/a, $b := /root/b, $res := $a + $b return $res";

var compiler = proc.newXQueryCompiler();
var executable = compiler.compile(expression);
var selector = executable.load();
selector.setContextItem(doc);

return selector.evaluate();

结果是0.30000000000000004。根据这个问题 () 这是因为默认的 number/xs:double 类型。

但是,我有一个 XSD,其中元素 ab 具有 xs:decimal 类型。有什么方法可以告诉 Saxon 在 XQuery 表达式执行时使用来自 XSD 的类型?

更新

我获得了 SaxonEE 的试用许可证,并使用以下代码通过了许可证:

var conf = new com.saxonica.config.EnterpriseConfiguration();
conf.setConfigurationProperty(Feature.LICENSE_FILE_LOCATION, "/path/to/saxon-license.lic");

var proc = new Processor(conf);

我使用相同的 xml 文档和 xsd。在 xquery 表达式的序言中,我添加了一个 import schema:

import schema default element namespace "" at "/path/to/example.xsd";
let $a := /root/a, $b := /root/b, $res := $a + $b return $res

但结果还是0.30000000000000004。我做错了什么?

更新 2

根据这里的所有建议,是使用 Saxon-EE 的模式感知 XQuery 的工作示例:

var conf = new com.saxonica.config.EnterpriseConfiguration();
conf.setConfigurationProperty(Feature.LICENSE_FILE_LOCATION, "/path/to/saxon-license.lic");
conf.setSchemaValidationMode(net.sf.saxon.lib.Validation.STRICT);

var proc = new Processor(conf);

var schemaManager = proc.getSchemaManager();
var source = new SAXSource(new InputSource("/path/to/example.xsd"));
schemaManager.load(source);

var builder = proc.newDocumentBuilder();
builder.setBaseURI(URI.create("http://test.ru"));

var file = new File(filePath);
var doc = builder.build(file);

var prolog = "import schema default element namespace "" at "/path/to/example.xsd";"
var expression = prolog + "let $a := /root/a, $b := /root/b, $res := $a + $b return $res";

var compiler = proc.newXQueryCompiler();
var executable = compiler.compile(expression);
var selector = executable.load();
selector.setContextItem(doc);

return selector.evaluate();

如果您能够切换到 Saxon EE,那么您当然可以使用模式感知 XQuery,例如https://www.w3.org/TR/xquery-31/#id-schema-import and the schema will be used and your values will be xs:decimals. Or with the right settings the document might be parsed and validated based on the schemaLocation attribute (https://www.saxonica.com/html/documentation10/schema-processing/saqueryapi.html).

然而,即使在 HE 中,也没有什么能阻止您let $a := xs:decimal(/root/a), $b := xs:decimal(/root/b),您可能需要在查询序言中声明命名空间。