如何使用Saxon导入xquery模块

如何使用Saxon导入xquery模块,xquery,saxon,Xquery,Saxon,我在使用Saxon9HE运行Xquery时遇到一些问题,因为它引用了一个外部模块。 我希望Saxon用相对路径而不是绝对路径来解析模块 模块声明 module namespace common = "http://my-xquery-utils"; 从主xquery import module namespace common = "http://my-xquery-utils" at "/home/myself/common.xquery"; 从我的java代码 public class

我在使用Saxon9HE运行Xquery时遇到一些问题,因为它引用了一个外部模块。 我希望Saxon用相对路径而不是绝对路径来解析模块

模块声明

module namespace common = "http://my-xquery-utils";
从主xquery

import module namespace common = "http://my-xquery-utils" at "/home/myself/common.xquery";
从我的java代码

public class SaxonInvocator {

private static Processor proc = null;
private static XQueryEvaluator xqe = null;
private static DocumentBuilder db = null;
private static StaticQueryContext ctx = null;

/**
 * Utility for debug, should not be called outside your IDE
 *
 * @param args xml, xqFile, xqParameter
 */
public static void main(String[] args) {
    XmlObject instance = null;
    try {
        instance = XmlObject.Factory.parse(new File(args[0]));
    } catch (XmlException ex) {
        Logger.getLogger(SaxonInvocator.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex){
        Logger.getLogger(SaxonInvocator.class.getName()).log(Level.SEVERE, null, ex);
    }
    System.out.print(transform(instance, args[1], args[2]));
}

public static String transform(XmlObject input, String xqFile, String xqParameter) {
    String result = null;
    try {
        proc = new Processor(false);
        proc.getUnderlyingConfiguration().getOptimizer().setOptimizationLevel(0);
        ctx = proc.getUnderlyingConfiguration().newStaticQueryContext();
        ctx.setModuleURIResolver(new ModuleURIResolver() {

            @Override
            public StreamSource[] resolve(String moduleURI, String baseURI, String[] locations) throws XPathException {
                StreamSource[] modules = new StreamSource[locations.length];
                for (int i = 0; i < locations.length; i++) {
                    modules[i] = new StreamSource(getResourceAsStream(locations[i]));
                }
                return modules;
            }
        });

        db = proc.newDocumentBuilder();
        XQueryCompiler comp = proc.newXQueryCompiler();
        XQueryExecutable exp = comp.compile(getResourceAsStream(xqFile));
        xqe = exp.load();
        ByteArrayInputStream bais = new ByteArrayInputStream(input.xmlText().getBytes("UTF-8"));
        StreamSource ss = new StreamSource(bais);
        XdmNode node = db.build(ss);
        xqe.setExternalVariable(
                new QName(xqParameter), node);
        result = xqe.evaluate().toString();
    } catch (SaxonApiException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return result;
}

public static InputStream getResourceAsStream(String resource) {
    InputStream stream = SaxonInvocator.class.getResourceAsStream("/" + resource);
    if (stream == null) {
        stream = SaxonInvocator.class.getResourceAsStream(resource);
    }
    if (stream == null) {
        stream = SaxonInvocator.class.getResourceAsStream("my/project/" + resource);
    }
    if (stream == null) {
        stream = SaxonInvocator.class.getResourceAsStream("/my/project/" + resource);
    }
    return stream;
}
我明白了

第22行第1列出错 XQST0059:java.io.FileNotFoundException


我不确定ModuleRiResolver应该如何使用。

撒克逊问题最好在Saxon论坛上提出-这里提出的问题可能最终会被注意到,但有时,就像这次,它们不是我们的首要任务

基本答案是,要解析相对URI,需要知道基本URI,这意味着您需要确保设置XQueryCompiler中的baseURI属性。如果从文件编译查询,则会自动发生这种情况,但如果从InputStream编译查询,则不会发生这种情况


如果您不知道要设置一个合适的基本URI,另一种方法是编写一个ModuleRiResolver,例如,它可以通过再次调用getResourceAsStream()来获取模块。

Saxon问题最好在Saxon论坛上提出来-这里提出来的问题可能最终会被注意到,但有时,就像这次一样,它们不是我们的首要任务

基本答案是,要解析相对URI,需要知道基本URI,这意味着您需要确保设置XQueryCompiler中的baseURI属性。如果从文件编译查询,则会自动发生这种情况,但如果从InputStream编译查询,则不会发生这种情况


如果您不知道要设置的合适的基本URI,另一种方法是编写ModuleURIResolver,例如,它可以通过对getResourceAsStream()进行另一次调用来获取模块。

嗨,Michael,调用setModuleURIResolver没有帮助。我相信解决方法甚至没有被触发。实际拨打电话的时间/地点?只要没有外部模块进入,代码就可以工作,这仍然是使用setModuleURIResolver调用Saxon转换的正确方法吗?感谢您正在创建一个新的StaticQueryContext并在其上设置模块URI解析器,但您没有使用此StaticQueryContext进行编译。在XQueryCompiler本身上使用setModuleURIResolver。嗨,Michael,调用setModuleURIResolver没有帮助。我相信解决方法甚至没有被触发。实际拨打电话的时间/地点?只要没有外部模块进入,代码就可以工作,这仍然是使用setModuleURIResolver调用Saxon转换的正确方法吗?感谢您正在创建一个新的StaticQueryContext并在其上设置模块URI解析器,但您没有使用此StaticQueryContext进行编译。在XQueryCompiler本身上使用setModuleURIResolver。
import module namespace common = "http://my-xquery-utils" at "common.xquery";