Hi. I've found a strange behaviour with the xquery "replace node" command. It seems that new namespace declarations within the XML tree added are not taken into account. Please, find hereafter a JUnit test code.
Laurent
package com.cyim.basex.test.ns;
import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test;
import org.basex.server.ClientSession; import org.basex.util.Util;
/** * Test support of XML namespaces. * * @author Laurent Chevalier l.chevalier@cyim.com */ public final class NamespaceTest { /** Client session. */ private ClientSession session;
/** Database name. */ protected static final String DB = Util.name(NamespaceTest.class);
/** * Opens a client session, creates a database and loads documents. * @throws java.io.IOException IO exception */ @Before public void setUp() throws java.io.IOException { session = new ClientSession("localhost", 1984, "admin", "admin"); session.execute(String.format("create db %s <default/>", DB));
// Loads documents. addDoc("doc/1"); addDoc("doc/2"); addDoc("doc/3"); }
/** * Adds a document. * @param uri * @throws java.io.IOException */ private void addDoc(String uri) throws java.io.IOException { // Document content. java.lang.StringBuilder qs = new java.lang.StringBuilder(); qs.append("<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#%5C" xmlns:core="http://rdfs.cyim.com/CoreContent#%5C%22%3E%5Cn"); qs.append(String.format(" <core:Container rdf:about="%s"/>\n", uri)); qs.append("</rdf:RDF>");
// Adds it. java.io.InputStream in = new java.io.ByteArrayInputStream(qs.toString().getBytes("UTF-8")); try { session.add(uri, in); } finally { in.close(); } }
/** * Drops the database and close remaining client sessions. * @throws java.io.IOException IO exception */ @After public void tearDown() throws java.io.IOException { session.execute("drop db " + DB); session.close(); }
/** * Inserts a node. * * @param uri Document uri. * @throws java.io.IOException IO exception */ private void insertNode(String uri) throws java.io.IOException { java.lang.StringBuilder qs = new java.lang.StringBuilder("xquery\n"); qs.append("declare namespace rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#%5C%22;%5Cn"); qs.append("declare namespace core = "http://rdfs.cyim.com/CoreContent#%5C%22;%5Cn"); qs.append("declare namespace wfdata = "http://rdfs.cyim.com/WorkflowData#%5C%22;%5Cn"); qs.append("insert node ") .append("<wfdata:Workflow xmlns:wfdata="http://rdfs.cyim.com/WorkflowData#%5C%22%3E%5Cn") .append(" wfdata:raiseOn2011-11-01T11:34:08Z</wfdata:raiseOn>\n") .append("</wfdata:Workflow>\n") .append("into /rdf:RDF/*[@rdf:about="" + uri + ""] "); session.execute(qs.toString()); }
/** * Replaces a node and declares the 'wfdata' prefix on the 'core:Container' node. * * @param uri Document uri. * @throws java.io.IOException IO exception */ private void replaceNode(String uri) throws java.io.IOException { java.lang.StringBuilder qs = new java.lang.StringBuilder("xquery\n"); qs.append("declare namespace rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#%5C%22;%5Cn"); qs.append("declare namespace core = "http://rdfs.cyim.com/CoreContent#%5C%22;%5Cn"); qs.append("declare namespace wfdata = "http://rdfs.cyim.com/WorkflowData#%5C%22;%5Cn"); qs.append("replace node /rdf:RDF/*[@rdf:about="" + uri + ""] with <core:Container rdf:about="" + uri + "" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#%5C" xmlns:core="http://rdfs.cyim.com/CoreContent#%5C" xmlns:wfdata="http://rdfs.cyim.com/WorkflowData#%5C%22%3E%5Cn") .append(" wfdata:Workflow\n") .append(" wfdata:raiseOn2011-11-01T11:34:08Z</wfdata:raiseOn>\n") .append(" </wfdata:Workflow>\n") .append("</core:Container>\n"); session.execute(qs.toString()); }
/** * Replaces a node and declares the 'wfdata' prefix on the 'wfdata:Workflow' node. * * @param uri Document uri. * @throws java.io.IOException IO exception */ private void replaceNode2(String uri) throws java.io.IOException { java.lang.StringBuilder qs = new java.lang.StringBuilder("xquery\n"); qs.append("declare namespace rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#%5C%22;%5Cn"); qs.append("declare namespace core = "http://rdfs.cyim.com/CoreContent#%5C%22;%5Cn"); qs.append("declare namespace wfdata = "http://rdfs.cyim.com/WorkflowData#%5C%22;%5Cn"); qs.append("replace node /rdf:RDF/*[@rdf:about="" + uri + ""] with <core:Container rdf:about="" + uri + "" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#%5C" xmlns:core="http://rdfs.cyim.com/CoreContent#%5C%22%3E%5Cn") .append(" <wfdata:Workflow xmlns:wfdata="http://rdfs.cyim.com/WorkflowData#%5C%22%3E%5Cn") .append(" wfdata:raiseOn2011-11-01T11:34:08Z</wfdata:raiseOn>\n") .append(" </wfdata:Workflow>\n") .append("</core:Container>\n"); session.execute(qs.toString()); }
/** * Query. Select depending on added node. * * @param expected Number of expected results. * @throws java.io.IOException IO exception */ private void query(int expected) throws java.io.IOException { // Query using wildcards. java.lang.StringBuilder qs = new java.lang.StringBuilder("xquery\n"); qs.append("declare namespace rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#%5C%22;%5Cn"); qs.append("for $c in /rdf:RDF/*[//*:raiseOn<"2011-11-02T14:19:07Z"]\n"); qs.append("return <item about="{data($c/@rdf:about)}" raiseOn="{data($c//*:raiseOn)}"/>\n"); String results = session.execute(qs.toString()); System.out.println("\n" + qs.toString() + "\n" + results); Assert.assertEquals("Missing results!", expected, results.isEmpty()?0:results.split("\r\n|\r|\n").length);
// Query using namespace. qs = new java.lang.StringBuilder("xquery\n"); qs.append("declare namespace rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#%5C%22;%5Cn"); qs.append("declare namespace wfdata = "http://rdfs.cyim.com/WorkflowData#%5C%22;%5Cn"); qs.append("for $c in /rdf:RDF/*[//wfdata:raiseOn<"2011-11-02T14:19:07Z"]\n"); qs.append("return <item about="{data($c/@rdf:about)}" raiseOn="{data($c//wfdata:raiseOn)}"/>\n"); results = session.execute(qs.toString()); System.out.println("\n" + qs.toString() + "\n" + results); Assert.assertEquals("Missing results!", expected, results.isEmpty()?0:results.split("\r\n|\r|\n").length); }
/** * Test entry point. * @throws java.io.IOException IO exception */ @Test public void run() throws java.io.IOException { System.out.println("Query using unchanged documents."); query(0);
System.out.println("\nInserts a node to doc/1."); insertNode("doc/1");
System.out.println("\nQuery. Should get 1 document."); query(1);
System.out.println("\nReplaces a node in doc/2 and declares the 'wfdata' prefix on the 'core:Container' node.\n."); replaceNode("doc/2");
System.out.println("\nQuery. Should get 2 documents."); query(2);
System.out.println("\nReplaces a node in doc/3 and declares the 'wfdata' prefix on the 'wfdata:Workflow' node.\n."); replaceNode2("doc/3");
System.out.println("\nDatabase content:"); System.out.println(session.execute("xquery /"));
System.out.println("\nQuery. Should get 3 documents."); System.out.println("This test is going to fail without wildcards as if the new node linked to 'wfdata' prefix was not seen."); query(3); } }
Hi Laurent,
we are currently revising our internal namespace structures and are quite positive that this issue will be resolved in the process. For now we are a bit hesitant to include further fixes that might blow up the code unnecessarily and cost us precious time better spent on the revision of the module itself.
Thanks for the detailed test - we will include this into the testing process. I also opened a GitHub issue as a reminder [1].
Sorry for the inconveniences - regards, Lukas
Thanks for your quick answer.
Just a precision : you can reproduce the problem by calling replaceNode2() directly without calling neither insertNode() nor replaceNode() before. The problem occurs when the replace command does not declare the new namespace at the top level node.
Regards, Laurent
De : Lukas Kircher [mailto:lukaskircher1@googlemail.com] Envoyé : mercredi 2 novembre 2011 17:26 À : Laurent Chevalier Cc : basex-talk@mailman.uni-konstanz.de Objet : Re: [basex-talk] 'replace node' with new XML namespace prefix
Hi Laurent,
we are currently revising our internal namespace structures and are quite positive that this issue will be resolved in the process. For now we are a bit hesitant to include further fixes that might blow up the code unnecessarily and cost us precious time better spent on the revision of the module itself.
Thanks for the detailed test - we will include this into the testing process. I also opened a GitHub issue as a reminder [1].
Sorry for the inconveniences - regards, Lukas
Thanks a lot. This already simplifies it a great deal ...
Have a nice evening, Lukas
On Wed, Nov 2, 2011 at 5:34 PM, Laurent Chevalier l.chevalier@cyim.comwrote:
Thanks for your quick answer. ****
Just a precision : you can reproduce the problem by calling replaceNode2() directly without calling neither insertNode() nor replaceNode() before. The problem occurs when the replace command does not declare the new namespace at the top level node.****
Regards, ****
Laurent****
*De :* Lukas Kircher [mailto:lukaskircher1@googlemail.com] *Envoyé :* mercredi 2 novembre 2011 17:26 *À :* Laurent Chevalier *Cc :* basex-talk@mailman.uni-konstanz.de *Objet :* Re: [basex-talk] 'replace node' with new XML namespace prefix***
Hi Laurent,****
we are currently revising our internal namespace structures and are quite positive that this issue will be resolved in the process. For now we are a bit hesitant to include further fixes that might blow up the code unnecessarily and cost us precious time better spent on the revision of the module itself.****
Thanks for the detailed test - we will include this into the testing process. I also opened a GitHub issue as a reminder [1].****
Sorry for the inconveniences - regards,****
Lukas****
Hi Laurent,
we identified and fixed the problem today - thanks to your test case. Feel free to checkout our git sources [1].
The next latest stable snapshot will also reflect the changes [2], but I'm not exactly sure when it will be released. We might move this task up on our todo list ...
Regards, Lukas
[1] https://github.com/BaseXdb/basex [2] http://basex.org/products/download/all-downloads/
Dear Laurent,
I've just updated the latest snapshots; to be found at
http://files.basex.org/releases/latest/
Hope this helps, Christian ___________________________
we identified and fixed the problem today - thanks to your test case. Feel free to checkout our git sources [1]. The next latest stable snapshot will also reflect the changes [2], but I'm not exactly sure when it will be released. We might move this task up on our todo list ...
Regards, Lukas [1] https://github.com/BaseXdb/basex [2] http://basex.org/products/download/all-downloads/ _______________________________________________ BaseX-Talk mailing list BaseX-Talk@mailman.uni-konstanz.de https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk
Hi Lukas,
Thank you very much for this fix.
Regards, Laurent
De : Lukas Kircher [mailto:lukaskircher1@googlemail.com] Envoyé : jeudi 10 novembre 2011 12:22 À : Laurent Chevalier Cc : basex-talk@mailman.uni-konstanz.de Objet : Re: [basex-talk] 'replace node' with new XML namespace prefix
Hi Laurent,
we identified and fixed the problem today - thanks to your test case. Feel free to checkout our git sources [1].
The next latest stable snapshot will also reflect the changes [2], but I'm not exactly sure when it will be released. We might move this task up on our todo list ...
Regards, Lukas
[1] https://github.com/BaseXdb/basex [2] http://basex.org/products/download/all-downloads/
basex-talk@mailman.uni-konstanz.de