我刚刚从 Saxon EE 9.6.0.4 升级到 9.8.0.12,现在在以下代码中,我在调用 setContextItem() 时遇到异常
XPathExecutable exe = xPath.compile(query);
XPathSelector selector = exe.load();
selector.setContextItem(xmlDocument);
我创建 xpath 对象如下:
void ctor(InputStream xmlData, InputStream schemaFile, boolean preserveWhiteSpace) throws SAXException, SchemaException, SaxonApiException {
this.rootNode = new XpathDataSourceNode();
Map xsdNamespaces = new HashMap();
XMLReader reader = XMLReaderFactory.createXMLReader();
//reader.setEntityResolver(runtime.);
InputSource xmlSource = new InputSource(xmlData);
SAXSource saxSource = new SAXSource(reader, xmlSource);
Source schemaSource = new StreamSource(schemaFile);
Configuration config = createEnterpriseConfiguration();
config.addSchemaSource(schemaSource);
Processor processor = new Processor(config);
SchemaValidator validator = new SchemaValidatorImpl(processor);
DocumentBuilder doc_builder = processor.newDocumentBuilder();
if(!preserveWhiteSpace)
doc_builder.setWhitespaceStrippingPolicy(WhitespaceStrippingPolicy.ALL);
doc_builder.setSchemaValidator(validator);
XdmNode root_node = doc_builder.build(saxSource);
XPathCompiler compiler = processor.newXPathCompiler();
declareNameSpaces(root_node, compiler);
this.xmlRootNode = root_node;
this.xPath = compiler;
在这种情况下我需要做什么不同的事情?
谢谢 - 戴夫
您需要设置
compiler.SchemaAware = true;
引入检查(和错误消息)是因为早期版本在这种情况下会产生不正确的结果:将 SchemaAware
属性设置为 false 时,优化器假定所有原子化内容均为 xs:untypedAtomic
,如果输入文档已通过架构验证,则这是不正确的。更改优化器以消除此假设将导致所有非架构感知 XPath 用户(即大多数用户)的性能下降。
请注意,如果您要使用 XPath 查询类型化数据,那么 XPath 编译器最好能够访问架构,这样它实际上可以利用数据类型化这一事实。但是,其范围是有限的,因为 XPath API 没有与 XQuery 中的 XQueryCompiler.ContextItemType
属性等效的属性,该属性允许静态声明上下文项的类型。因此,实际上 XPath 编译器无法根据模式信息进行许多静态推断(或检测许多错误)。
我是一名优秀的程序员,十分优秀!