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



我有以下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。根据这个问题(SaxonHE XQuery sum operation precision),这是因为默认的number/xs:double类型。

但是,我有一个XSD,其中元素ab具有xs:decimal类型。在XQuery表达式执行过程中,是否有办法从XSD中告诉Saxon使用类型?

我已经获得了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,模式将被使用,你的值将是xs:decimals。或者通过正确的设置,可以根据schemaLocation属性(https://www.saxonica.com/html/documentation10/schema-processing/saqueryapi.html)解析和验证文档。

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

最新更新