我需要使用XQuery插入表达式将一个新元素插入到XML文档中。我使用saxon
作为java api。我是XQuery的新手,所以我不确定插入表达式的确切结构。有人能帮我吗。
我的XML文件如下所示:
<?xml version="1.0" encoding="ISO-8859-1"?>
<breakfast_menu>
<food>
<name>Belgian Waffles</name>
<price>$5.95</price>
<description>two of our famous Belgian Waffles with plenty of real maple syrup<description>
<calories>650</calories>
</food>
</breakfast_menu>
我执行插入的java代码是
public void insert() throws XQException{
String queryString =
//"declare variable $docName as xs:string external;" + sep +
"variable $stores := doc("+"food.xml"+")/*;"+
"insert node element food {"+
"element name { "brnj" },"+
"element price { "$20" },"+
"element description { "whatever" },"+
"element calories { 300 },"+
"} into $stores;";
XQPreparedExpression expr = conn.prepareExpression(queryString);
expr.bindObject(new QName("stores"), "food.xml", null);
XQResultSequence rs = expr.executeQuery();
}
我得到的错误是在查询字符串的语法中。请帮忙。
XQJ API不支持XQuery更新。我相信有些供应商已经扩展了XQJ以支持更新,但由于XQJ的许可条件会对任何试图扩展API的人处以死刑,我在Saxon中避免了这样做。(我也不知道有任何定义此类扩展的举措——XQJ从一开始就被律师扼杀了,原因我一直不明白。)
如果您使用Saxon作为XQuery更新引擎,我建议您使用s9api接口。这里有一个例子:
public void run() throws SaxonApiException {
Processor proc = new Processor(true);
XQueryCompiler comp = proc.newXQueryCompiler();
comp.setUpdatingEnabled(true);
XQueryExecutable exp = comp.compile(
"for $p in doc('data/books.xml')//PRICE " +
"return replace value of node $p with $p + 0.05");
XQueryEvaluator eval = exp.load();
eval.run();
for (Iterator<XdmNode> iter = eval.getUpdatedDocuments(); iter.hasNext();) {
XdmNode root = iter.next();
URI rootUri = root.getDocumentURI();
if (rootUri != null && rootUri.getScheme().equals("file")) {
try {
Serializer out = proc.newSerializer(new FileOutputStream(new File(rootUri)));
out.setOutputProperty(Serializer.Property.METHOD, "xml");
out.setOutputProperty(Serializer.Property.INDENT, "yes");
out.setOutputProperty(Serializer.Property.OMIT_XML_DECLARATION, "yes");
System.err.println("Rewriting " + rootUri);
proc.writeXdmValue(root, out);
} catch (FileNotFoundException e) {
System.err.println("Could not write to file " + rootUri);
}
} else {
System.err.println("Updated document not rewritten: location unknown or not updatable");
}
}
}
最复杂的是将更新后的文档写回文件库——当然,这不一定是您想要做的。
请注意,XQueryUpdate仅在Saxon的商业版中受支持。
BaseX XQJ API支持XQueryUpdate Facility 1.0和3.0,它允许您更新BaseX数据库中的文档。
您也可以通过MarkLogic XQJ API、Sedna XQJ API和eXist XQJ API更新数据库中的文档,尽管不通过XQuery更新工具,因为这些实现还不支持XQUF。
最后,对于您的问题,可能也是最重要的一点,您可能会发现Ryan Grimm的"内存内更新"库模块非常有用[1]。我当然有,在过去无数次。
你可以
- 将库模块与ANY XQuery处理器+XQJ一起使用
- 对内存中的XML文档执行更新(无需写入磁盘)
- 在一个XQuery中对文档执行"多个"更新操作
- 内存中更新后的文档可以在XQResultSequence中返回(非常适合您)
此外,为了明确起见,XQJ 1.0规范并没有禁止供应商支持XQuery更新功能。
规范摘录:
"18.6对更新和事务的支持
尽管更新功能不是[XQuery]的一部分,但XQJ预计实现将包括一些专有的扩展来处理更新功能。"
[1]https://github.com/marklogic/commons/blob/master/memupdate/in-mem-update.xqy
现在有可能了。
上传查询:
public static void ejecutarConsultaU(String cadenaAConsultar) throws XQException {
XQExpression consulta;
consulta = xqc.createExpression();
System.out.println("Inicio consulta n");
System.out.println(cadenaAConsultar);
System.out.println("fin consulta n");
consulta.executeCommand(cadenaAConsultar);}
插入/选择查询:
public static void ejecutarConsulta(String cadenaAConsultar) throws XQException {
XQPreparedExpression consulta;
consulta = xqc.prepareExpression(cadenaAConsultar);
XQResultSequence resultado = consulta.executeQuery();
}