1

我需要使用 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();
}

我得到的错误是查询字符串的语法。请帮忙。

4

3 回答 3

2

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");
            }
        }
    }

大部分复杂性在于将更新的文档写回文件存储区——当然,这不一定是您想要做的。

请注意,XQuery 更新仅在 Saxon 的商业版本中受支持。

于 2012-07-12T07:51:02.767 回答
1

BaseX XQJ API 支持 XQuery Update Facility 1.0 和 3.0,它允许您更新 BaseX 数据库中的文档。

您还可以通过 MarkLogic XQJ API、Sedna XQJ API 和 eXist XQJ API 更新数据库内文档,但不能通过 XQuery 更新工具,因为这些实现(目前)还不支持 XQUF。

最后,对于您的问题,可能最重要的是,您可能会发现 Ryan Grimm 的“in-mem-update”库模块非常有用 [1]。我当然有,过去无数次。

你可以

  • 将库模块与任何 XQuery 处理器 + XQJ 一起使用
  • 对内存中的 XML 文档执行更新(无需写入磁盘)。
  • 在单个 XQuery 中对文档执行“多个”更新操作
  • 可以在 XQResultSequence 中返回更新后的内存中文档(非常适合您)。

另外,为了明确一点,XQJ 1.0 规范并没有禁止供应商支持 XQuery Update Facility。

规范摘录:

"18.6 支持更新和事务

尽管更新功能不是 [XQuery] 的一部分,但 XQJ 预计某些实现将包括一些专有扩展来处理更新功能。”

[1] https://github.com/marklogic/commons/blob/master/memupdate/in-mem-update.xqy

于 2012-07-12T14:51:51.243 回答
1

现在是可能的。

上传查询:

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();
}
于 2015-05-06T00:41:47.607 回答