最近在看XQuery,没到一个可以输入XML和XQuery显示结果的平台。用开源的MXQuery写了一个,以便可以看到结果学习XQuery的语法,函数,自定义函数等
package org.sz.xquery;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import ch.ethz.mxquery.contextConfig.CompilerOptions;
import ch.ethz.mxquery.contextConfig.Context;
import ch.ethz.mxquery.exceptions.MXQueryException;
import ch.ethz.mxquery.model.XDMIterator;
import ch.ethz.mxquery.query.PreparedStatement;
import ch.ethz.mxquery.query.XQCompiler;
import ch.ethz.mxquery.query.impl.CompilerImpl;
import ch.ethz.mxquery.xdmio.XDMSerializer;
public class XQTester {
private static void testXQ(String query) throws Exception {
boolean updateFiles = true;
Context ctx = new Context();
CompilerOptions options = new CompilerOptions();
options.setSchemaAwareness(true);
options.setUpdate(true);
ctx.getStores().setUseUpdateStores(true);
ctx.getStores().setSerializeStores(updateFiles);
XQCompiler complier = new CompilerImpl();
PreparedStatement statement;
try {
statement = complier.compile(ctx, query, options);
XDMIterator result = statement.evaluate();
XDMSerializer ip = new XDMSerializer();
String _return = ip.eventsToXML(result);
//去掉XML header
int utf_end = _return.indexOf(">");
_return = _return.substring(utf_end + 2, _return.length());
log(_return);
} catch (MXQueryException e) {
MXQueryException.printErrorPosition(query, e.getLocation());
System.err.println("Error:");
throw e;
}
}
private static<T extends Object> void log(T t) {
//toString();
System.out.println(t);
}
public static String getXQueryFromFile(URL url) {
File file = new File(url.getFile());
String suffix = getSuffix(file.getName());
if (!suffix.equalsIgnoreCase("xq")) {
throw new RuntimeException("目标文件不是.xq文件");
}
StringBuilder sb = new StringBuilder();
try {
String line = "";
BufferedReader fis = new BufferedReader(new InputStreamReader
(new FileInputStream(file)));
while((line = fis.readLine()) != null) {
sb.append(line);
sb.append("\n");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new RuntimeException("目标不是文件");
} catch (IOException ex) {
ex.printStackTrace();
throw new RuntimeException("目标文件错误");
}
return sb.toString();
}
private static String getSuffix(String fileName) {
return fileName.substring(fileName.lastIndexOf(".") + 1);
}
public static void main(String[] args) throws Exception {
//String queryPrices = "doc('prices.xml')//priceList[prod/@num = 557]" ;
//String queryCatalog = "doc('catalog.xml')//name/substring(., 1, 3)";
String basePath = XQTester.class.getClassLoader().getResource(".").getPath();
final String sep = File.separator;
String xqString = "file:/" + basePath + "org" + sep + "sz" + sep + "fn" + sep + "add-element.xq";
URL url = new URL(xqString);
String fnDefine = getXQueryFromFile(url);
String fnCall = fnDefine + "doc('catalog.xml')//product/functx:add-attribute(., 'attr', 1)";
testXQ(fnCall);
}
}
XQuery函数
declare namespace functx = "http://www.functx.com";
declare function functx:add-attribute
($element as element(), $name as xs:string,
$value as xs:anyAtomicType?) as element() {
element { node-name($element) }
{ attribute {$name} {$value},
$element/@*,
$element/node() }
};