Вставить элемент в XML с помощью XQuery и Java

Мне нужно вставить новый элемент в документ XML, используя выражение вставки XQuery. Я использую 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();
}

ошибка, которую я получаю, связана с синтаксисом строки запроса. Пожалуйста помоги.


person Lucy    schedule 12.07.2012    source источник


Ответы (3)


BaseX XQJ API поддерживает XQuery Update Facility 1.0 и 3.0, что позволяет обновлять документы в базе данных BaseX.

Вы также можете обновлять документы в базе данных через MarkLogic XQJ API, Sedna XQJ API и eXist XQJ API, но не через XQuery Update Facility, поскольку эти реализации не поддерживают XQUF (пока).

Наконец, и, возможно, самое главное для вашего вопроса, вы можете найти очень полезным модуль библиотеки «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

person Charles Foster    schedule 12.07.2012

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 Update поддерживается только в коммерческих версиях Saxon.

person Michael Kay    schedule 12.07.2012
comment
Спасибо за ваш ответ, значит ли это, что саксон также не поддерживает вставки? - person Lucy; 12.07.2012
comment
Saxon поддерживает все обновления XQuery, включая вставки, но не через XQJ API. - person Michael Kay; 12.07.2012

Теперь это возможно.

Загрузить запросы:

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();
}
person idelcano    schedule 06.05.2015