1
我遇到一些麻煩,運行一個帶有Saxon9HE的Xquery,它有一個外部模塊的引用。 我想撒克遜解決與相對路徑相當絕對的模塊。如何導入一個使用Saxon的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;
}
}
模塊聲明
module namespace common = "http://my-xquery-utils";
從主的XQuery
import module namespace common = "http://my-xquery-utils" at "/home/myself/common.xquery";
如果把它變成像一個相對路徑
import module namespace common = "http://my-xquery-utils" at "common.xquery";
我得到的線22列
錯誤1 XQST0059:java.io.FileNotFoundException
我不知道該ModuleURIResolver應該如何使用。
嗨邁克爾,調用setModuleURIResolver沒有幫助。我相信解決方法甚至沒有觸發。 何時/何地應該實際進行呼叫? 只要沒有外部模塊進來,該代碼就可以工作,那仍然是用setModuleURIResolver調用Saxon轉換的正確方法嗎? 謝謝 – AleIla
這裏的代碼已經更新 – AleIla
你正在創建一個新的StaticQueryContext並設置模塊URI解析器,但是你沒有使用這個StaticQueryContext來編譯。在XQueryCompiler本身上使用setModuleURIResolver。 –