package org.exist.xquery;
import org.exist.jetty.JettyStart;
import org.exist.TestUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.exist.xmldb.CollectionImpl;
import org.exist.xmldb.DatabaseInstanceManager;
import org.exist.xmldb.XPathQueryServiceImpl;
import org.exist.xmldb.XmldbURI;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.JUnitCore;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xmldb.api.DatabaseManager;
import org.xmldb.api.base.*;
import org.xmldb.api.modules.CollectionManagementService;
import org.xmldb.api.modules.XMLResource;
import org.xmldb.api.modules.XPathQueryService;
import org.xmldb.api.modules.XQueryService;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
public class XPathQueryTest {
private final static String nested =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<test><c></c><b><c><b></b></c></b><b></b><c></c></test>";
private final static String numbers =
"<test>"
+ "<item id='1' type='alphanum'><price>5.6</price><stock>22</stock></item>"
+ "<item id='2'><price>7.4</price><stock>43</stock></item>"
+ "<item id='3'><price>18.4</price><stock>5</stock></item>"
+ "<item id='4'><price>65.54</price><stock>16</stock></item>"
+ "</test>";
private final static String numbers2 =
"<test xmlns=\"http://numbers.org\">"
+ "<item id='1' type='alphanum'><price>5.6</price><stock>22</stock></item>"
+ "<item id='2'><price>7.4</price><stock>43</stock></item>"
+ "<item id='3'><price>18.4</price><stock>5</stock></item>"
+ "<item id='4'><price>65.54</price><stock>16</stock></item>"
+ "</test>";
private final static String namespaces =
"<test xmlns='http://www.foo.com'>"
+ " <section>"
+ " <title>Test Document</title>"
+ " <c:comment xmlns:c='http://www.other.com'>This is my comment</c:comment>"
+ " </section>"
+ "</test>";
private final static String strings =
"<test>"
+ "<string>Hello World!</string>"
+ "<string value='Hello World!'/>"
+ "<string>Hello</string>"
+ "</test>";
private final static String nested2 =
"<RootElement>" +
"<ChildA>" +
"<ChildB id=\"2\"/>" +
"</ChildA>" +
"</RootElement>";
private final static String nested3 =
"<test>" +
" <a>" +
" <t>1</t>" +
" <a>" +
" <t>2</t>" +
" <a>" +
" <t>3</t>" +
" </a>" +
" </a>" +
" </a>" +
"</test>";
private final static String siblings =
"<test>" +
" <a> <s>A</s> <n>1</n> </a>" +
" <a> <s>Z</s> <n>2</n> </a>" +
" <a> <s>B</s> <n>3</n> </a>" +
" <a> <s>Z</s> <n>4</n> </a>" +
" <a> <s>C</s> <n>5</n> </a>" +
" <a> <s>Z</s> <n>6</n> </a>" +
"</test>";
private final static String ids =
"<!DOCTYPE test [" +
"<!ELEMENT test (a | b | c | d)*>" +
"<!ATTLIST test xml:space CDATA #IMPLIED>" +
"<!ELEMENT a EMPTY>" +
"<!ELEMENT b (name)>" +
"<!ELEMENT c (name)>" +
"<!ELEMENT d EMPTY>" +
"<!ATTLIST d ref IDREF #IMPLIED>" +
"<!ELEMENT name (#PCDATA)>" +
"<!ATTLIST a ref IDREF #IMPLIED>" +
"<!ATTLIST b id ID #IMPLIED>" +
"<!ATTLIST c xml:id ID #IMPLIED>]>" +
"<test xml:space=\"preserve\">" +
"<a ref=\"id1\"/>" +
"<a ref=\"id1\"/>" +
"<d ref=\"id2\"/>" +
"<b id=\"id1\"><name>one</name></b>" +
"<c xml:id=\" id2 \"><name>two</name></c>" +
"</test>";
private final static String date =
"<timestamp date=\"2006-04-29+02:00\"/>";
private final static String quotes =
"<test><title>"Hello"</title></test>";
private final static String ws =
"<test><parent xml:space=\"preserve\"><text> </text><text xml:space=\"default\"> </text></parent></test>";
private final static String self =
"<test-self><a>Hello</a><b>World!</b></test-self>";
private final static String predicates =
"<elem1>\n" +
" <elem2>\n" +
" <elem3/>\n" +
" </elem2>\n" +
" <elem2>\n" +
" <elem3>val1</elem3>\n" +
" </elem2>\n" +
" <elem2>\n" +
" <elem3>val2</elem3>\n" +
" </elem2>\n" +
"</elem1>";
// Added by Geoff Shuetrim (geoff@galexy.net) to highlight problems with XPath queries of elements called 'xpointer'.
private final static String xpointerElementName =
"<test><xpointer/></test>";
private static String uri = XmldbURI.LOCAL_DB;
public static void setURI(String collectionURI) {
uri = collectionURI;
}
private static JettyStart server = null;
private Collection testCollection;
@Before
public void setUp() throws Exception {
if (uri.startsWith("xmldb:exist://localhost")) {
initServer();
}
// initialize driver
Class<?> cl = Class.forName("org.exist.xmldb.DatabaseImpl");
Database database = (Database) cl.newInstance();
database.setProperty("create-database", "true");
DatabaseManager.registerDatabase(database);
Collection root =
DatabaseManager.getCollection(
uri,
"admin",
"");
CollectionManagementService service =
(CollectionManagementService) root.getService(
"CollectionManagementService",
"1.0");
testCollection = service.createCollection("test");
assertNotNull(testCollection);
}
private void initServer() {
if (server == null) {
server = new JettyStart();
System.out.println("Starting standalone server...");
server.run();
}
}
@After
public void tearDown() throws Exception {
TestUtils.cleanupDB();
if (!((CollectionImpl) testCollection).isRemoteCollection()) {
DatabaseInstanceManager dim =
(DatabaseInstanceManager) testCollection.getService(
"DatabaseInstanceManager", "1.0");
dim.shutdown();
}
testCollection = null;
}
@Test
public void pathExpression() throws XMLDBException {
final XQueryService service =
storeXMLStringAndGetQueryService("numbers.xml", numbers);
//Invalid path expression left operand (not a node set).
String message = "";
try {
queryAndAssert(service, "('a', 'b', 'c')/position()", -1, null);
} catch (XMLDBException e) {
message = e.getMessage();
}
assertTrue("Exception wanted: " + message, message.indexOf("XPTY0019") > -1);
//Undefined context sequence
message = "";
try {
queryAndAssert(service, "for $a in (<a/>, <b/>, doh, <c/>) return $a", -1, null);
} catch (XMLDBException e) {
message = e.getMessage();
}
assertTrue("Exception wanted: " + message, message.indexOf("XPDY0002") > -1);
message = "";
try {
//"1 to 2" is resolved as a (1, 2), i.e. a sequence of *integers* which is *not* a singleton
queryAndAssert(service, "let $a := (1, 2, 3) for $b in $a[1 to 2] return $b", -1, null);
} catch (XMLDBException e) {
message = e.getMessage();
}
//No effective boolean value for such a kind of sequence !
assertTrue("Exception wanted: " + message, message.indexOf("FORG0006") >-1);
queryAndAssert(service, "let $a := ('a', 'b', 'c') return $a[2 to 2]", 1, null);
queryAndAssert(service, "let $a := ('a', 'b', 'c') return $a[(2 to 2)]", 1, null);
queryAndAssert(service, "let $x := <a min='1' max='10'/> return ($x/@min to $x/@max)", 10, null);
queryAndAssert(service, "(1,2,3)[xs:decimal(.)]", 3, null);
queryAndAssert(service, "(1,2,3)[. lt 3]", 2, null);
queryAndAssert(service, "(0, 1, 2)[if(. eq 1) then 0 else position()]", 2, null);
queryAndAssert(service, "(1, 2, 3)[if(1) then 1 else last()]", 1, null);
queryAndAssert(service, "(1, 2, 3)[if(1) then 1 else position()]", 1, null);
queryAndAssert(service, "()/position()", 0, null);
queryAndAssert(service, "(0, 1, 2)[if(. eq 1) then 2 else 3]", 2, null);
queryAndAssert(service, "(0, 1, 2)[remove((1, 'a string'), 2)]", 1, null);
queryAndAssert(service, "let $page-ix := (1,3) return ($page-ix[1] to $page-ix[2])", 3, null);
}
/** test simple queries involving attributes */
@Test
public void attributes() throws XMLDBException {
final String testDocument = "numbers.xml";
final XQueryService service = storeXMLStringAndGetQueryService(
testDocument, numbers);
String query = "/test/item[ @id='1' ]";
ResourceSet result = service.queryResource(testDocument, query);
System.out.println("testAttributes 1: ========");
printResult(result);
assertEquals("XPath: " + query, 1, result.getSize());
XMLResource resource = (XMLResource)result.getResource(0);
Node node = resource.getContentAsDOM();
if (node.getNodeType() == Node.DOCUMENT_NODE)
node = node.getFirstChild();
assertEquals("XPath: " + query, "item", node.getNodeName());
query = "/test/item [ @type='alphanum' ]";
result = service.queryResource(testDocument, query);
System.out.println("testAttributes 2: ========");
printResult(result);
assertEquals("XPath: " + query, 1, result.getSize());
}
@Test
public void starAxis() throws XMLDBException {
final XQueryService service =
storeXMLStringAndGetQueryService("numbers.xml", numbers);
ResourceSet result = service.queryResource("numbers.xml", "/*/item");
System.out.println("testStarAxis 1: ========");
printResult(result);
assertEquals("XPath: /*/item", 4, result.getSize());
result = service.queryResource("numbers.xml", "/test/*");
System.out.println("testStarAxis 2: ========");
printResult(result);
assertEquals("XPath: /test/*", 4, result.getSize());
result = service.queryResource("numbers.xml", "/test/descendant-or-self::*");
System.out.println("testStarAxis 3: ========");
printResult(result);
assertEquals("XPath: /test/descendant-or-self::*", 13, result.getSize());
result = service.queryResource("numbers.xml", "/*/*");
System.out.println("testStarAxis 4: ========" );
printResult(result);
//Strange !!! Should be 8
assertEquals("XPath: /*/*", 4, result.getSize());
}
@Test
public void starAxisConstraints() throws XMLDBException {
final XQueryService service =
storeXMLStringAndGetQueryService("namespaces.xml", namespaces);
service.setNamespace("t", "http://www.foo.com");
System.out.println("testStarAxisConstraints : ========");
String query = "// t:title/text() [ . != 'aaaa' ]";
ResourceSet result = service.queryResource( "namespaces.xml", query);
printResult(result);
assertEquals("XPath: " + query, 1, result.getSize() );
System.out.println("testStarAxisConstraints : ========");
query = "/t:test/*:section[contains(., 'comment')]";
result = service.queryResource("namespaces.xml", query);
printResult(result);
assertEquals("XPath: " + query, 1, result.getSize());
System.out.println("testStarAxisConstraints : ========");
query = "/t:test/t:*[contains(., 'comment')]";
result = service.queryResource("namespaces.xml", query);
printResult(result);
assertEquals("XPath: " + query, 1, result.getSize());
System.out.println("testStarAxisConstraints : ========");
query = "/t:test/t:section[contains(., 'comment')]";
result = service.queryResource("namespaces.xml", query);
printResult(result);
assertEquals("XPath: " + query, 1, result.getSize());
System.out.println("testStarAxisConstraints : ========");
query = "/t:test/t:section/*[contains(., 'comment')]";
result = service.queryResource("namespaces.xml", query);
printResult(result);
assertEquals("XPath: " + query, 1, result.getSize());
System.out.println("testStarAxisConstraints : ========");
query = "/ * / * [ t:title ]";
result = service.queryResource( "namespaces.xml", query);
printResult(result);
assertEquals("XPath: " + query, 1, result.getSize() );
System.out.println("testStarAxisConstraints : ========");
query = "/ t:test / t:section [ t:title ]";
result = service.queryResource( "namespaces.xml", query);
printResult(result);
System.out.println("g) 1 / " + result.getSize());
assertEquals("XPath: " + query, 1, result.getSize() );
System.out.println("testStarAxisConstraints : ========");
query = "/ t:test / t:section";
result = service.queryResource( "namespaces.xml", query);
printResult(result);
System.out.println("h) 1 / " + result.getSize());
assertEquals("XPath: " + query, 1, result.getSize() );
System.out.println("testStarAxisConstraints : ========");
}
@Test
public void starAxisConstraints2() throws XMLDBException {
final XQueryService service =
storeXMLStringAndGetQueryService("namespaces.xml", namespaces);
service.setNamespace("t", "http://www.foo.com");
String query = "/ * [ ./ * / t:title ]";
ResourceSet result = service.queryResource( "namespaces.xml", query);
System.out.println("testStarAxisConstraints2 : ========");
printResult(result);
assertEquals("XPath: " + query, 1, result.getSize());
query = "/ * [ * / t:title ]";
result = service.queryResource( "namespaces.xml", query);
System.out.println("testStarAxisConstraints2 : ========");
printResult(result);
assertEquals("XPath: " + query, 1, result.getSize());
}
@Test
public void starAxisConstraints3() throws XMLDBException {
final XQueryService service =
storeXMLStringAndGetQueryService("namespaces.xml", namespaces);
service.setNamespace("t", "http://www.foo.com");
final String query = "// * [ . = 'Test Document' ]";
final ResourceSet result = service.queryResource("namespaces.xml", query);
System.out.println("testStarAxisConstraints3 : ========");
printResult(result);
assertEquals("XPath: " + query, 1, result.getSize());
}
@Test
public void root() throws XMLDBException {
storeXMLStringAndGetQueryService("nested2.xml", nested2);
final XQueryService service = storeXMLStringAndGetQueryService("numbers.xml", numbers);
String query = "let $doc := <a><b/></a> return root($doc)";
ResourceSet result = service.queryResource("numbers.xml", query);
assertEquals("XPath: " + query, 1, result.getSize());
final XMLResource resource = (XMLResource)result.getResource(0);
Node node = resource.getContentAsDOM();
//Oh dear ! Don't tell me that *I* have written this :'( -pb
if (node.getNodeType() == Node.DOCUMENT_NODE) {
node = node.getFirstChild();
}
assertEquals("XPath: " + query, "a", node.getLocalName());
query = "let $c := (<a/>,<b/>,<c/>,<d/>,<e/>) return count($c/root())";
result = service.queryResource("numbers.xml", query);
assertEquals("5", result.getResource(0).getContent().toString());
}
@Test
public void name() throws XMLDBException {
final XQueryService service =
storeXMLStringAndGetQueryService("nested2.xml", nested2);
final String query = "(<a/>,<b/>)/name()";
final ResourceSet result = service.queryResource("nested2.xml", query);
assertEquals("XPath: " + query, 2, result.getSize());
assertEquals("a", result.getResource(0).getContent().toString());
assertEquals("b", result.getResource(1).getContent().toString());
}
@Test
public void parentAxis() throws XMLDBException {
XQueryService service =
storeXMLStringAndGetQueryService("nested2.xml", nested2);
queryResource(service, "nested2.xml", "(<a/>, <b/>, <c/>)/parent::*", 0);
queryResource(service, "nested2.xml", "/RootElement//ChildB/parent::*", 1);
queryResource(service, "nested2.xml", "/RootElement//ChildB/parent::*/ChildB", 1);
queryResource(service, "nested2.xml", "/RootElement/ChildA/parent::*/ChildA/ChildB", 1);
service =
storeXMLStringAndGetQueryService("numbers2.xml", numbers2);
service.setNamespace("n", "http://numbers.org");
queryResource(service, "numbers2.xml", "//n:price[. = 18.4]/parent::*[@id = '3']", 1);
queryResource(service, "numbers2.xml", "//n:price[. = 18.4]/parent::n:item[@id = '3']", 1);
queryResource(service, "numbers2.xml", "//n:price/parent::n:item[@id = '3']", 1);
ResourceSet result =
queryResource(service, "numbers2.xml", "//n:price[. = 18.4]/parent::n:*/string(@id)", 1);
assertEquals("3", result.getResource(0).getContent().toString());
result = queryResource(service, "numbers2.xml", "//n:price[. = 18.4]/parent::*:item/string(@id)", 1);
assertEquals("3", result.getResource(0).getContent().toString());
result = queryResource(service, "numbers2.xml", "//n:price[. = 18.4]/../string(@id)", 1);
assertEquals("3", result.getResource(0).getContent().toString());
result = queryResource(service, "numbers2.xml", "//n:price[. = 18.4]/parent::n:item/string(@id)", 1);
assertEquals("3", result.getResource(0).getContent().toString());
queryResource(service, "numbers2.xml",
"for $price in //n:price where $price/parent::*[@id = '3']/n:stock = '5' return $price", 1);
}
@Test
public void parentSelfAxis() throws XMLDBException {
final XQueryService service =
storeXMLStringAndGetQueryService("nested2.xml", nested2);
storeXMLStringAndGetQueryService("numbers.xml", numbers);
queryResource(service, "nested2.xml", "/RootElement/descendant::*/parent::ChildA", 1);
queryResource(service, "nested2.xml", "/RootElement/descendant::*[self::ChildB]/parent::RootElement", 0);
queryResource(service, "nested2.xml", "/RootElement/descendant::*[self::ChildA]/parent::RootElement", 1);
queryResource(service, "nested2.xml", "let $a := ('', 'b', '', '') for $b in $a[.] return <blah>{$b}</blah>", 1);
final String query = "let $doc := <root><page><a>a</a><b>b</b></page></root>" +
"return " +
"for $element in $doc/page/* " +
"return " +
"if($element[self::a] or $element[self::b]) then (<found/>) else (<notfound/>)";
final ResourceSet result = service.queryResource("numbers.xml", query);
assertEquals(2, result.getSize());
}
@Test
public void selfAxis() throws XMLDBException {
final XQueryService service =
storeXMLStringAndGetQueryService("self.xml", self);
queryResource(service, "self.xml", "/test-self/*[not(self::a)]", 1);
queryResource(service, "self.xml", "/test-self/*[self::a]", 1);
}
@Test
public void ancestorAxis() throws XMLDBException {
final XQueryService service =
storeXMLStringAndGetQueryService("nested3.xml", nested3);
// test ancestor axis with positional predicate
queryResource(service, "nested3.xml", "//a[ancestor::a[2]/t = '1']", 1);
queryResource(service, "nested3.xml", "//a[ancestor::*[2]/t = '1']", 1);
queryResource(service, "nested3.xml", "//a[ancestor::a[1]/t = '2']", 1);
queryResource(service, "nested3.xml", "//a[ancestor::*[1]/t = '2']", 1);
queryResource(service, "nested3.xml", "//a[ancestor-or-self::*[3]/t = '1']", 1);
queryResource(service, "nested3.xml", "//a[ancestor-or-self::a[3]/t = '1']", 1);
// Following test fails
// queryResource(service, "nested3.xml", "//a[ancestor-or-self::*[2]/t = '2']", 1);
queryResource(service, "nested3.xml", "//a[ancestor-or-self::a[2]/t = '2']", 1);
queryResource(service, "nested3.xml", "//a[t = '3'][ancestor-or-self::a[3]/t = '1']", 1);
queryResource(service, "nested3.xml", "//a[t = '3'][ancestor-or-self::*[3]/t = '1']", 1);
}
@Test
public void ancestorIndex() throws XMLDBException {
final XQueryService service =
storeXMLStringAndGetQueryService("nested2.xml", nested2);
queryResource(service, "nested2.xml", "//ChildB/ancestor::*[1]/self::ChildA", 1);
queryResource(service, "nested2.xml", "//ChildB/ancestor::*[2]/self::RootElement", 1);
queryResource(service, "nested2.xml", "//ChildB/ancestor::*[position() = 1]/self::ChildA", 1);
queryResource(service, "nested2.xml", "//ChildB/ancestor::*[position() = 2]/self::RootElement", 1);
queryResource(service, "nested2.xml", "//ChildB/ancestor::*[position() = 2]/self::RootElement", 1);
queryResource(service, "nested2.xml", "(<a/>, <b/>, <c/>)/ancestor::*", 0);
}
@Test
public void precedingSiblingAxis() throws XMLDBException, IOException, SAXException {
final XQueryService service =
storeXMLStringAndGetQueryService("siblings.xml", siblings);
service.setProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
service.setProperty(OutputKeys.INDENT, "no");
ResourceSet result = queryResource(service, "siblings.xml", "//a[preceding-sibling::*[1]/s = 'B']", 1);
assertXMLEqual("<a><s>Z</s><n>4</n></a>", result.getResource(0).getContent().toString());
result = queryResource(service, "siblings.xml", "//a[preceding-sibling::a[1]/s = 'B']", 1);
assertXMLEqual("<a><s>Z</s><n>4</n></a>", result.getResource(0).getContent().toString());
result = queryResource(service, "siblings.xml", "//a[preceding-sibling::*[2]/s = 'B']", 1);
assertXMLEqual("<a><s>C</s><n>5</n></a>", result.getResource(0).getContent().toString());
result = queryResource(service, "siblings.xml", "//a[preceding-sibling::a[2]/s = 'B']", 1);
assertXMLEqual("<a><s>C</s><n>5</n></a>", result.getResource(0).getContent().toString());
queryResource(service, "siblings.xml", "(<a/>, <b/>, <c/>)/following-sibling::*", 0);
}
@Test
public void followingSiblingAxis() throws XMLDBException, IOException, SAXException {
final XQueryService service =
storeXMLStringAndGetQueryService("siblings.xml", siblings);
service.setProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
service.setProperty(OutputKeys.INDENT, "no");
ResourceSet result = queryResource(service, "siblings.xml", "//a[following-sibling::*[1]/s = 'B']", 1);
assertXMLEqual("<a><s>Z</s><n>2</n></a>", result.getResource(0).getContent().toString());
result = queryResource(service, "siblings.xml", "//a[following-sibling::a[1]/s = 'B']", 1);
assertXMLEqual("<a><s>Z</s><n>2</n></a>", result.getResource(0).getContent().toString());
result = queryResource(service, "siblings.xml", "//a[following-sibling::*[2]/s = 'B']", 1);
assertXMLEqual("<a><s>A</s><n>1</n></a>", result.getResource(0).getContent().toString());
result = queryResource(service, "siblings.xml", "//a[following-sibling::a[2]/s = 'B']", 1);
assertXMLEqual("<a><s>A</s><n>1</n></a>", result.getResource(0).getContent().toString());
queryResource(service, "siblings.xml", "(<a/>, <b/>, <c/>)/following-sibling::*", 0);
service.setProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
service.setProperty(OutputKeys.INDENT, "no");
ResourceSet rs = service.query("let $doc := <doc><div id='1'><div id='2'/></div><div id='3'/></doc> " +
"return $doc/div[1]/following-sibling::div");
assertEquals(1, rs.getSize());
assertXMLEqual("<div id='3'/>", rs.getResource(0).getContent().toString());
service.setProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
service.setProperty(OutputKeys.INDENT, "no");
rs = service.query("let $doc := <doc><div id='1'/><div id='2'><div id='3'/></div><div id='4'/><div id='5'><div id='6'/></div></doc> " +
"return $doc/div/preceding-sibling::div");
assertEquals(3, rs.getSize());
assertXMLEqual("<div id='1'/>", rs.getResource(0).getContent().toString());
assertXMLEqual("<div id='2'><div id='3'/></div>", rs.getResource(1).getContent().toString());
assertXMLEqual("<div id='4'/>", rs.getResource(2).getContent().toString());
}
@Test
public void followingAxis() throws XMLDBException, IOException, SAXException {
final XQueryService service =
storeXMLStringAndGetQueryService("siblings.xml", siblings);
service.setProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
service.setProperty(OutputKeys.INDENT, "no");
queryResource(service, "siblings.xml", "//a/s[. = 'B']/following::s", 3);
queryResource(service, "siblings.xml", "//a/s[. = 'B']/following::n", 4);
ResourceSet result = queryResource(service, "siblings.xml", "//a/s[. = 'B']/following::s[1]", 1);
assertXMLEqual("<s>Z</s>", result.getResource(0).getContent().toString());
result = queryResource(service, "siblings.xml", "//a/s[. = 'B']/following::s[2]", 1);
assertXMLEqual("<s>C</s>", result.getResource(0).getContent().toString());
}
@Test
public void precedingAxis() throws XMLDBException {
final XQueryService service =
storeXMLStringAndGetQueryService("siblings.xml", siblings);
service.setProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
service.setProperty(OutputKeys.INDENT, "no");
queryResource(service, "siblings.xml", "//a/s[. = 'B']/preceding::s", 2);
queryResource(service, "siblings.xml", "//a/s[. = 'C']/preceding::s", 4);
queryResource(service, "siblings.xml", "//a/n[. = '3']/preceding::s", 3);
}
@Test
public void position() throws XMLDBException, IOException, SAXException {
final XQueryService service =
storeXMLStringAndGetQueryService("numbers.xml", numbers);
queryResource(service, "numbers.xml", "//item[position() = 3]", 1);
queryResource(service, "numbers.xml", "//item[position() < 3]", 2);
queryResource(service, "numbers.xml", "//item[position() <= 3]", 3);
queryResource(service, "numbers.xml", "//item[position() > 3]", 1);
queryResource(service, "numbers.xml", "//item[position() >= 3]", 2);
queryResource(service, "numbers.xml", "//item[position() eq 3]", 1);
queryResource(service, "numbers.xml", "//item[position() lt 3]", 2);
queryResource(service, "numbers.xml", "//item[position() le 3]", 3);
queryResource(service, "numbers.xml", "//item[position() gt 3]", 1);
queryResource(service, "numbers.xml", "//item[position() ge 3]", 2);
queryResource(service, "numbers.xml", "//item[last() - 1]", 1);
queryResource(service, "numbers.xml", "//item[count(('a','b')) - 1]", 1);
String query = "for $a in (<a/>, <b/>, <c/>) return $a/position()";
ResourceSet result = service.queryResource("numbers.xml", query);
assertEquals("XPath: " + query, 3, result.getSize());
XMLResource resource = (XMLResource)result.getResource(0);
assertEquals("XPath: " + query, "1", resource.getContent().toString());
resource = (XMLResource)result.getResource(1);
assertEquals("XPath: " + query, "1", resource.getContent().toString());
resource = (XMLResource)result.getResource(2);
assertEquals("XPath: " + query, "1", resource.getContent().toString());
query = "declare variable $doc { <root>" +
"<a>1</a><a>2</a><a>3</a><a>4</a><a>5</a><a>6</a><a>7</a>" +
"</root> }; " +
"(for $x in $doc/a return $x)[position() mod 3 = 2]";
result = service.queryResource("numbers.xml", query);
assertEquals("XPath: " + query, 2, result.getSize());
query = "declare variable $doc { <root>" +
"<a>1</a><a>2</a><a>3</a><a>4</a><a>5</a><a>6</a><a>7</a>" +
"</root> }; " +
"for $x in $doc/a return $x[position() mod 3 = 2]";
result = service.queryResource("numbers.xml", query);
assertEquals("XPath: " + query, 0, result.getSize());
query = "declare variable $doc { <root>" +
"<a>1</a><a>2</a><a>3</a><a>4</a><a>5</a><a>6</a><a>7</a>" +
"</root> }; " +
"for $x in $doc/a[position() mod 3 = 2] return $x";
result = service.queryResource("numbers.xml", query);
assertEquals("XPath: " + query, 2, result.getSize());
query = "let $test := <test><a> a </a><a>a</a></test>" +
"return distinct-values($test/a/normalize-space(.))";
result = service.queryResource("numbers.xml", query);
assertEquals("XPath: " + query, 1, result.getSize());
resource = (XMLResource)result.getResource(0);
assertEquals("XPath: " + query, "a", resource.getContent().toString());
query = "let $doc := document {<a><b n='1'/><b n='2'/></a>} " +
"return $doc//b/(if (@n = '1') then position() else ())";
result = service.queryResource("numbers.xml", query);
assertEquals("XPath: " + query, 1, result.getSize());
assertEquals("1", result.getResource(0).getContent().toString());
//Try a second time to see if the position is reset
result = service.queryResource("numbers.xml", query);
assertEquals("XPath: " + query, 1, result.getSize());
assertEquals("1", result.getResource(0).getContent().toString());
query = "let $doc := document {<a><b/></a>} " +
"return $doc/a[1] [b[1]]";
service.setProperty(OutputKeys.INDENT, "no");
result = service.queryResource("numbers.xml", query);
assertEquals("XPath: " + query, 1, result.getSize());
assertXMLEqual("<a><b/></a>", result.getResource(0).getContent().toString());
//TODO : make this work ! It currently returns some content
//query = "let $doc := document {<a><b><c>1</c></b><b><c>a</c></b></a>} " +
// "return $doc/a[b[position() = 2]/c[.='1']]";
//result = service.queryResource("numbers.xml", query);
//assertEquals("XPath: " + query, 0, result.getSize());
// TODO: make this work ! It currently returns 1
//query = "let $a := ('a', 'b', 'c') for $b in $a[position()] return <blah>{$b}</blah>";
//result = service.queryResource("numbers.xml", query);
//assertEquals("XPath: " + query, 3, result.getSize());
}
@Test
public void last() throws XMLDBException {
final XQueryService service =
storeXMLStringAndGetQueryService("numbers.xml", numbers);
final String query = "<a><b>test1</b><b>test2</b></a>/b/last()";
final ResourceSet result = service.queryResource("numbers.xml", query);
assertEquals("XPath: " + query, 2, result.getSize());
XMLResource resource = (XMLResource)result.getResource(0);
assertEquals("XPath: " + query, "2", resource.getContent().toString());
resource = (XMLResource)result.getResource(1);
assertEquals("XPath: " + query, "2", resource.getContent().toString());
}
@Test
public void numbers() throws XMLDBException {
final XQueryService service =
storeXMLStringAndGetQueryService("numbers.xml", numbers);
ResourceSet result = queryResource(service, "numbers.xml", "sum(/test/item/price)", 1);
assertEquals("96.94", result.getResource(0).getContent().toString());
result = queryResource(service, "numbers.xml", "round(sum(/test/item/price))", 1);
assertEquals("97", result.getResource(0).getContent().toString());
result = queryResource(service, "numbers.xml", "floor(sum(/test/item/stock))", 1);
assertEquals( "86", result.getResource(0).getContent().toString());
queryResource(service, "numbers.xml", "/test/item[round(price + 3) > 60]", 1);
result = queryResource(service, "numbers.xml", "min(( 123456789123456789123456789, " +
"123456789123456789123456789123456789123456789 ))", 1);
assertEquals("minimum of big integers",
"123456789123456789123456789",
result.getResource(0).getContent().toString());
String message = "";
try {
queryResource(service, "numbers.xml", "empty(() + (1, 2))", 1);
} catch (XMLDBException e) {
message = e.getMessage();
}
assertTrue(message.indexOf("XPTY0004") > -1);
}
@Test
public void dates() throws XMLDBException {
final XQueryService service =
storeXMLStringAndGetQueryService("numbers.xml", numbers);
String query = "xs:untypedAtomic(\"--12-05:00\") cast as xs:gMonth";
ResourceSet result = service.queryResource("numbers.xml", query);
XMLResource resource = (XMLResource)result.getResource(0);
assertEquals("XPath: " + query, "--12-05:00", resource.getContent().toString());
query = "(xs:dateTime(\"0001-01-01T01:01:01Z\") + xs:yearMonthDuration(\"-P20Y07M\"))";
result = service.queryResource("numbers.xml", query);
resource = (XMLResource)result.getResource(0);
assertEquals("XPath: " + query, "-0021-06-01T01:01:01Z", resource.getContent().toString());
}
@Test
public void generalComparison() throws XMLDBException {
final XQueryService service =
storeXMLStringAndGetQueryService("dates.xml", date);
queryResource(service, "dates.xml", "/timestamp[@date = xs:date('2006-04-29+02:00')]", 1);
}
@Test
public void predicates() throws XMLDBException, IOException, SAXException {
final String numbers =
"<test>"
+ "<item id='1' type='alphanum'><price>5.6</price><stock>22</stock></item>"
+ "<item id='2'><price>7.4</price><stock>43</stock></item>"
+ "<item id='3'><price>18.4</price><stock>5</stock></item>"
+ "<item id='4'><price>65.54</price><stock>16</stock></item>"
+ "</test>";
final XQueryService service =
storeXMLStringAndGetQueryService("numbers.xml", numbers);
service.setProperty(OutputKeys.INDENT, "no");
ResourceSet result = queryResource(service, "numbers.xml", "/test/item[2]/price/text()", 1);
assertEquals("7.4", result.getResource(0).getContent().toString());
result = queryResource(service, "numbers.xml", "/test/item[5]", 0);
result = queryResource(service, "numbers.xml", "/test/item[@id='4'][1]/price[1]/text()", 1);
assertEquals("65.54",
result.getResource(0).getContent().toString());
result = queryResource(service, "numbers.xml", "for $i in //item return " +
"<item>{$i/price, $i/stock}</item>", 4);
assertXMLEqual("<item><price>5.6</price><stock>22</stock></item>",
result.getResource(0).getContent().toString());
assertXMLEqual("<item><price>65.54</price><stock>16</stock></item>",
result.getResource(3).getContent().toString());
// test positional predicates
result = queryResource(service, "numbers.xml", "/test/node()[2]", 1);
assertXMLEqual("<item id='2'><price>7.4</price><stock>43</stock></item>",
result.getResource(0).getContent().toString());
result = queryResource(service, "numbers.xml", "/test/element()[2]", 1);
assertXMLEqual("<item id='2'><price>7.4</price><stock>43</stock></item>",
result.getResource(0).getContent().toString());
// positional predicate on sequence of atomic values
result = queryResource(service, "numbers.xml", "('test', 'pass')[2]", 1);
assertEquals("pass", result.getResource(0).getContent().toString());
result = queryResource(service, "numbers.xml", "let $credentials := ('test', 'pass') let $user := $credentials[1] return $user", 1);
assertEquals("test", result.getResource(0).getContent().toString());
result = queryResource(service, "numbers.xml", "let $credentials := ('test', 'pass') let $user := $credentials[2] return $user", 1);
assertEquals("pass", result.getResource(0).getContent().toString());
result = queryResource(service, "numbers.xml", "let $els := <els><el>text1</el><el>text2</el></els> return $els/el[xs:string(.) eq 'text1'] ", 1);
assertEquals("<el>text1</el>", result.getResource(0).getContent().toString());
}
@Test
public void predicates2() throws XMLDBException, IOException, SAXException {
final String numbers =
"<test>"
+ "<item id='1' type='alphanum'><price>5.6</price><stock>22</stock></item>"
+ "<item id='2'><price>7.4</price><stock>43</stock></item>"
+ "<item id='3'><price>18.4</price><stock>5</stock></item>"
+ "<item id='4'><price>65.54</price><stock>16</stock></item>"
+ "</test>";
final XQueryService service =
storeXMLStringAndGetQueryService("numbers.xml", numbers);
service.setProperty(OutputKeys.INDENT, "no");
String query = "let $t := <test>" + "<a> <s>A</s> 1 </a>"
+ "<a> <s>Z</s> 2 </a>" + "<a> <s>B</s> 3 </a>"
+ "<a> <s>Z</s> 4 </a>" + "<a> <s>C</s> 5 </a>"
+ "<a> <s>Z</s> 6 </a>" + "</test>"
+ "return $t//a[s='Z' and preceding-sibling::*[1]/s='B']";
ResourceSet result = queryResource(service, "numbers.xml", query, 1);
assertXMLEqual("<a><s>Z</s> 4 </a>", result.getResource(0)
.getContent().toString());
query = "let $t := <test>" + "<a> <s>A</s> 1 </a>"
+ "<a> <s>Z</s> 2 </a>" + "<a> <s>B</s> 3 </a>"
+ "<a> <s>Z</s> 4 </a>" + "<a> <s>C</s> 5 </a>"
+ "<a> <s>Z</s> 6 </a>" + "</test>"
+ "return $t//a[s='Z' and ./preceding-sibling::*[1]/s='B']";
result = queryResource(service, "numbers.xml", query, 1);
assertXMLEqual("<a><s>Z</s> 4 </a>", result.getResource(0)
.getContent().toString());
query = "let $doc := <doc><rec n='1'><a>first</a><b>second</b></rec>" +
"<rec n='2'><a>first</a><b>third</b></rec></doc> " +
"return $doc//rec[fn:not(b = 'second') and (./a = 'first')]";
result = queryResource(service, "numbers.xml", query, 1);
assertXMLEqual("<rec n=\"2\"><a>first</a><b>third</b></rec>", result.getResource(0)
.getContent().toString());
query = "let $doc := <doc><a b='c' d='e'/></doc> " +
"return $doc/a[$doc/a/@b or $doc/a/@d]";
result = queryResource(service, "numbers.xml", query, 1);
assertXMLEqual("<a b=\"c\" d=\"e\"/>", result.getResource(0)
.getContent().toString());
query = "let $x := <a><b><x/><x/></b><b><x/></b></a>" +
"return $x//b[count(x) = 2]";
result = queryResource(service, "numbers.xml", query, 1);
assertXMLEqual("<b><x/><x/></b>", result.getResource(0)
.getContent().toString());
//Boolean evaluation for "." (atomic sequence)
query = "(1,2,3)[xs:decimal(.)]";
result = queryResource(service, "numbers.xml", query, 3);
query = "(1,2,3)[number()]";
result = queryResource(service, "numbers.xml", query, 3);
query = " let $c := (<a/>,<b/>), $i := 1 return $c[$i]";
result = queryResource(service, "numbers.xml", query, 1);
assertXMLEqual("<a/>", result.getResource(0)
.getContent().toString());
query = "(1,2,3)[position() = last()]";
result = queryResource(service, "numbers.xml", query, 1);
assertEquals("3", result.getResource(0).getContent().toString());
query = "(1,2,3)[max(.)]";
result = queryResource(service, "numbers.xml", query, 3);
query = "(1,2,3)[max(.[. gt 1])]";
result = queryResource(service, "numbers.xml", query, 2);
assertEquals("2", result.getResource(0).getContent().toString());
assertEquals("3", result.getResource(1).getContent().toString());
query = "(1,2,3)[.]";
result = queryResource(service, "numbers.xml", query, 3);
query = "declare function local:f ($n) { " +
"$n " +
"}; " +
" " +
"declare function local:g( $n ) { " +
"('OK','Fine','Wrong') [local:f($n) + 1 ] " +
"} ; " +
" " +
"declare function local:h( $n ) { " +
"('OK','Fine','Wrong') [local:f($n) ] " +
"} ; " +
" " +
"declare function local:j( $n ) { " +
"let $m := local:f($n) " +
"return " +
"('OK','Fine','Wrong') [$m + 1 ] " +
"} ; " +
" " +
"declare function local:k ( $n ) { " +
"('OK','Fine','Wrong') [ $n + 1 ] " +
"} ; " +
" " +
"local:f(1),local:g(1), local:h(1), local:j(1), local:k(1) ";
result = queryResource(service, "numbers.xml", query, 5);
assertEquals("1", result.getResource(0).getContent().toString());
assertEquals("Fine", result.getResource(1).getContent().toString());
assertEquals("OK", result.getResource(2).getContent().toString());
assertEquals("Fine", result.getResource(3).getContent().toString());
assertEquals("Fine", result.getResource(4).getContent().toString());
//The collection doesn't exist : let's see how the query behaves with empty sequences
query = "let $checkDate := xs:date(adjust-date-to-timezone(current-date(), ())) " +
"let $collection := if (xmldb:collection-available(\"/db/lease\")) then collection(\"/db/lease\") else () " +
"for $x in " +
"$collection//Lease/Events/Type/Event[(When/Date<=$checkDate or " +
"When/EstimateDate<=$checkDate) and not(Status='Complete')] " +
"return $x";
result = queryResource(service, "numbers.xml", query, 0);
query = "let $res := <test><element name='A'/><element name='B'/></test> " +
"return " +
"for $name in ('A', 'B') return " +
"$res/element[@name=$name][1]";
result = queryResource(service, "numbers.xml", query, 2);
assertXMLEqual("<element name='A'/>", result.getResource(0).getContent().toString());
assertXMLEqual("<element name='B'/>", result.getResource(1).getContent().toString());
}
/**
* @see http://sourceforge.net/tracker/index.php?func=detail&aid=1460610&group_id=17691&atid=117691
*/
@Test
public void predicates_bug1460610() throws XMLDBException {
final String xQuery = "(1, 2, 3)[ . lt 3]";
final XQueryService service = getQueryService();
final ResourceSet rs = service.query(xQuery);
assertEquals("SFBUG 1460610 nr of results", 2, rs.getSize());
assertEquals("SFBUG 1460610 1st result", "1",
rs.getResource(0).getContent().toString());
assertEquals("SFBUG 1460610 2nd result", "2",
rs.getResource(1).getContent().toString());
}
/**
* @see http://sourceforge.net/tracker/index.php?func=detail&aid=1537355&group_id=17691&atid=117691
*/
@Test
public void predicates_bug1537355() throws XMLDBException {
final String xQuery = "let $one := 1 return (1, 2, 3)[$one + 1]";
final XQueryService service = getQueryService();
final ResourceSet rs = service.query(xQuery);
assertEquals("SFBUG 1537355 nr of results", 1, rs.getSize());
assertEquals("SFBUG 1537355 result", "2",
rs.getResource(0).getContent().toString());
}
/**
* @see http://sourceforge.net/tracker/index.php?func=detail&aid=1533053&group_id=17691&atid=117691
*/
@Test
public void nestedPredicates_bug1533053() throws XMLDBException, IOException, SAXException {
String xQuery = "let $doc := <objects>" +
"<detail><class/><source><dynamic>false</dynamic></source></detail>" +
"<detail><class/><source><dynamic>true</dynamic></source></detail>" +
"</objects> " +
"let $matches := $doc/detail[source[dynamic='false'] or class] " +
"return count($matches) eq 2";
XQueryService service = getQueryService();
ResourceSet rs = service.query(xQuery);
assertEquals(1, rs.getSize());
assertEquals("true", rs.getResource(0).getContent().toString());
xQuery = "let $xml := <test><element>" +
"<complexType><attribute name=\"design\" fixed=\"1\"/></complexType>" +
"</element></test> " +
"return $xml//element[complexType/attribute[@name eq \"design\"]/@fixed eq \"1\"]";
service = getQueryService();
service.setProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
service.setProperty(OutputKeys.INDENT, "no");
rs = service.query(xQuery);
assertEquals(1, rs.getSize());
assertXMLEqual("<element><complexType><attribute name=\"design\" fixed=\"1\"/></complexType></element>",
rs.getResource(0).getContent().toString());
}
/**
* @see http://sourceforge.net/tracker/index.php?func=detail&aid=1488303&group_id=17691&atid=117691
*/
@Test
public void predicate_bug1488303() throws XMLDBException {
XQueryService service = getQueryService();
ResourceSet rs=null;
// test one
final String xQuery1 = "let $q := <q><t>eXist</t></q> return $q//t";
rs = service.query(xQuery1);
assertEquals("nr of results", 1, rs.getSize());
assertEquals("result", "<t>eXist</t>",
rs.getResource(0).getContent().toString());
// test two
final String xQuery2 = "let $q := <q><t>eXist</t></q> return ($q//t)[1]";
rs = service.query(xQuery2);
assertEquals("nr of results", 1, rs.getSize());
assertEquals("result", "<t>eXist</t>",
rs.getResource(0).getContent().toString());
// This one fails http://sourceforge.net/tracker/index.php?func=detail&aid=1488303&group_id=17691&atid=117691
final String xQuery3 = "let $q := <q><t>eXist</t></q> return $q//t[1]";
rs = service.query(xQuery3);
assertEquals("SFBUG 1488303 nr of results", 1, rs.getSize());
assertEquals("SFBUG 1488303 result", "<t>eXist</t>",
rs.getResource(0).getContent().toString());
}
/**
* @see http://sourceforge.net/tracker/index.php?func=detail&aid=1460791&group_id=17691&atid=117691
*/
@Test
public void descendantOrSelf_bug1460791() throws XMLDBException {
final String xQuery = "declare option exist:serialize \"method=xml indent=no\"; let $test:=<z><a>aaa</a><z>zzz</z></z> "
+"return ( <one>{$test//z}</one>, <two>{$test/descendant-or-self::node()/child::z}</two> )";
final XQueryService service = getQueryService();
final ResourceSet rs = service.query(xQuery);
System.out.println("BUG1460791/1" + rs.getResource(0).getContent().toString() );
System.out.println("BUG1460791/2" + rs.getResource(1).getContent().toString() );
assertEquals("SFBUG 1460791 nr of results", 2, rs.getSize());
assertEquals("SFBUG 1460791 result part 1", "<one><z>zzz</z></one>",
rs.getResource(0).getContent().toString());
assertEquals("SFBUG 1460791 result part 2", "<two><z>zzz</z></two>",
rs.getResource(1).getContent().toString());
}
/**
* @see http://sourceforge.net/tracker/index.php?func=detail&aid=1462120&group_id=17691&atid=1176
*/
@Test
public void xpath_bug1462120() throws XMLDBException {
final String xQuery = "declare option exist:serialize \"method=xml indent=no\"; "
+"let $m:=<Units><Unit name=\"g\" size=\"1\"/>"
+"<Unit name=\"kg\" size=\"1000\"/></Units> "
+"let $list:=(<Product aaa=\"g\"/>, <Product aaa=\"kg\"/>) "
+"let $one:=$list[1] return ( "
+"$m/Unit[string(data(@name)) eq string(data($list[1]/@aaa))],"
+"<br/>,$m/Unit[string(data(@name)) eq string(data($one/@aaa))] )";
final XQueryService service = getQueryService();
final ResourceSet rs = service.query(xQuery);
assertEquals("SFBUG 1462120 nr of results", 3, rs.getSize());
assertEquals("SFBUG 1462120 result part 1", "<Unit name=\"g\" size=\"1\"/>",
rs.getResource(0).getContent().toString());
assertEquals("SFBUG 1462120 result part 2", "<br/>",
rs.getResource(1).getContent().toString());
assertEquals("SFBUG 1462120 result part 3", "<Unit name=\"g\" size=\"1\"/>",
rs.getResource(2).getContent().toString());
}
/**
* In Predicate.java, the contextSet and the outerSequence.toNodeSet()
* documents are different so that no match can occur.
*
* @see http://wiki.exist-db.org/space/XQueryBugs
*/
@Test
public void predicate_bug_wiki_1() throws XMLDBException {
final String xQuery = "let $dum := <dummy><el>1</el><el>2</el></dummy> return $dum/el[2]";
final XQueryService service = getQueryService();
final ResourceSet rs = service.query(xQuery);
assertEquals("Predicate bug wiki_1", 1, rs.getSize());
assertEquals("Predicate bug wiki_1", "<el>2</el>",
rs.getResource(0).getContent().toString());
}
@Test
public void predicate_bug_andrzej() throws XMLDBException {
final String xQuery =
"doc('/db/test/predicates.xml')//elem1/elem2[ string-length( ./elem3 ) > 0][1]/elem3/text()";
final XQueryService service =
storeXMLStringAndGetQueryService("predicates.xml", predicates);
final ResourceSet rs = service.query(xQuery);
assertEquals("testPredicateBUGAndrzej", 1, rs.getSize());
assertEquals("testPredicateBUGAndrzej", "val1", rs.getResource(0).getContent().toString());
}
/**
* removing Self: makes the query work OK
* @see http://wiki.exist-db.org/space/XQueryBugs
*/
@Test
public void cardinalitySelf_bug_wiki_2() throws XMLDBException {
final String xQuery = "let $test := <test><works><employee>a</employee><employee>b</employee></works></test> "
+ "for $h in $test/works/employee[2] return fn:name($h/self::employee)";
final XQueryService service = getQueryService();
final ResourceSet rs = service.query(xQuery);
assertEquals("CardinalitySelfBUG bug wiki_2", 1, rs.getSize());
assertEquals("CardinalitySelfBUG bug wiki_2", "employee",
rs.getResource(0).getContent().toString());
}
/**
* Problem in VirtualNodeSet which return 2 attributes because it
* computes every level
* @see http://wiki.exist-db.org/space/XQueryBugs
*/
@Test
public void virtualNodeset_bug_wiki_3() throws XMLDBException {
final String xQuery = "declare option exist:serialize \"method=xml indent=no\"; "
+ "let $node := (<c id=\"OK\"><b id=\"cool\"/></c>)"
+ "/descendant::*/attribute::id return <a>{$node}</a>";
final XQueryService service = getQueryService();
final ResourceSet rs = service.query(xQuery);
assertEquals("VirtualNodesetBUG_wiki_3", 1, rs.getSize());
assertEquals("VirtualNodesetBUG_wiki_3", "<a id=\"cool\"/>",
rs.getResource(0).getContent().toString());
}
/**
* Problem in VirtualNodeSet because it computes the wrong level
*
* @see http://wiki.exist-db.org/space/XQueryBugs
*/
@Test
public void virtualNodeset_bug_wiki_4() throws XMLDBException {
final String xQuery = "declare option exist:serialize \"method=xml indent=no\"; "
+ "let $node := (<c id=\"OK\">"
+ "<b id=\"cool\"/></c>)/descendant-or-self::*/child::b "
+ "return <a>{$node}</a>";
final XQueryService service = getQueryService();
final ResourceSet rs = service.query(xQuery);
assertEquals("VirtualNodesetBUG_wiki_4", 1, rs.getSize());
assertEquals("VirtualNodesetBUG_wiki_4", "<a><b id=\"cool\"/></a>",
rs.getResource(0).getContent().toString());
}
/**
* Problem in VirtualNodeSet because it computes the wrong level
*
* @see http://wiki.exist-db.org/space/XQueryBugs
*/
@Test
public void virtualNodeset_bug_wiki_5() throws XMLDBException {
final String xQuery = "declare option exist:serialize \"method=xml indent=no\"; "
+ "let $node := (<c id=\"OK\"><b id=\"cool\"/>"
+ "</c>)/descendant-or-self::*/descendant::b return <a>{$node}</a>";
final XQueryService service = getQueryService();
final ResourceSet rs = service.query(xQuery);
assertEquals("VirtualNodesetBUG_wiki_5", 1, rs.getSize());
assertEquals("VirtualNodesetBUG_wiki_5", "<a><b id=\"cool\"/></a>",
rs.getResource(0).getContent().toString());
}
// It seems that the document builder receives events that are irrelevant.
@Test
public void documentBuilder_bug_wiki_6() throws XMLDBException {
final String xQuery = "declare option exist:serialize \"method=xml indent=no\"; "
+ "declare function local:test() {let $results := <dummy/>"
+ "return \"id\" }; "
+ "<wrapper><string id=\"{local:test()}\"/></wrapper>";
final XQueryService service = getQueryService();
final ResourceSet rs = service.query(xQuery);
assertEquals("testDocumentBuilderBUG_wiki_6", 1, rs.getSize());
assertEquals("testDocumentBuilderBUG_wiki_6", "<wrapper><string id=\"id\"/></wrapper>",
rs.getResource(0).getContent().toString());
}
@Test
public void castInPredicate_bug_wiki_7() throws XMLDBException {
final String xQuery = "let $number := 2, $list := (\"a\", \"b\", \"c\") return $list[xs:int($number * 2) - 1]";
final XQueryService service = getQueryService();
final ResourceSet rs = service.query(xQuery);
assertEquals("testCalculationInPredicate_wiki_7", 1, rs.getSize());
assertEquals("testCalculationInPredicate_wiki_7", "c",
rs.getResource(0).getContent().toString());
}
/**
* Miscomputation of the expression context in where clause when no
* wrapper expression is used. Using, e.g. where data($x/@id) eq "id" works !
*/
@Test
public void computation_bug_wiki_8() throws XMLDBException {
final String xQuery = "declare option exist:serialize \"method=xml indent=no\"; "
+ "let $a := element node1 { attribute id {'id'}, "
+ "element node1 { '1'},element node2 { '2'} }"
+ "for $x in $a where $x/@id eq \"id\" return $x";
final XQueryService service = getQueryService();
final ResourceSet rs = service.query(xQuery);
assertEquals("testComputationBug_wiki_8", 1, rs.getSize());
assertEquals("testComputationBug_wiki_8", "<node1 id=\"id\"><node1>1</node1><node2>2</node2></node1>",
rs.getResource(0).getContent().toString());
}
@Test
public void strings() throws XMLDBException {
final XQueryService service =
storeXMLStringAndGetQueryService("strings.xml", strings);
ResourceSet result = queryResource(service, "strings.xml", "substring(/test/string[1], 1, 5)", 1);
assertEquals("Hello", result.getResource(0).getContent().toString());
queryResource(service, "strings.xml", "/test/string[starts-with(string(.), 'Hello')]", 2);
result = queryResource(service, "strings.xml", "count(/test/item/price)", 1,
"Query should return an empty set (wrong document)");
assertEquals("0", result.getResource(0).getContent().toString());
}
@Test
public void quotes() throws XMLDBException {
final XQueryService service =
storeXMLStringAndGetQueryService("quotes.xml", quotes);
queryResource(service, "quotes.xml", "/test[title = '"Hello"']", 1);
service.declareVariable("content", ""Hello"");
queryResource(service, "quotes.xml", "/test[title = $content]", 1);
}
@Test
public void booleans() throws XMLDBException {
System.out.println("Testing effective boolean value of expressions ...");
final XQueryService service =
storeXMLStringAndGetQueryService("numbers.xml", numbers);
ResourceSet result = queryResource(service, "numbers.xml", "boolean(1.0)", 1);
assertEquals("boolean value of 1.0 should be true", "true", result.getResource(0).getContent().toString());
result = queryResource(service, "numbers.xml", "boolean(0.0)", 1);
assertEquals("boolean value of 0.0 should be false", "false", result.getResource(0).getContent().toString());
result = queryResource(service, "numbers.xml", "boolean(xs:double(0.0))", 1);
assertEquals("boolean value of double 0.0 should be false", "false", result.getResource(0).getContent().toString());
result = queryResource(service, "numbers.xml", "boolean(xs:double(1.0))", 1);
assertEquals("boolean value of double 1.0 should be true", "true", result.getResource(0).getContent().toString());
result = queryResource(service, "numbers.xml", "boolean(xs:float(1.0))", 1);
assertEquals("boolean value of float 1.0 should be true", "true", result.getResource(0).getContent().toString());
result = queryResource(service, "numbers.xml", "boolean(xs:float(0.0))", 1);
assertEquals("boolean value of float 0.0 should be false", "false", result.getResource(0).getContent().toString());
result = queryResource(service, "numbers.xml", "boolean(xs:integer(0))", 1);
assertEquals("boolean value of integer 0 should be false", "false", result.getResource(0).getContent().toString());
result = queryResource(service, "numbers.xml", "boolean(xs:integer(1))", 1);
assertEquals("boolean value of integer 1 should be true", "true", result.getResource(0).getContent().toString());
result = queryResource(service, "numbers.xml", "'true' cast as xs:boolean", 1);
assertEquals("boolean value of 'true' cast to xs:boolean should be true",
"true", result.getResource(0).getContent().toString());
result = queryResource(service, "numbers.xml", "'false' cast as xs:boolean", 1);
assertEquals("boolean value of 'false' cast to xs:boolean should be false",
"false", result.getResource(0).getContent().toString());
result = queryResource(service, "numbers.xml", "boolean('Hello')", 1);
assertEquals("boolean value of string 'Hello' should be true", "true", result.getResource(0).getContent().toString());
result = queryResource(service, "numbers.xml", "boolean('')", 1);
assertEquals("boolean value of empty string should be false", "false", result.getResource(0).getContent().toString());
result = queryResource(service, "numbers.xml", "boolean(())", 1);
assertEquals("boolean value of empty sequence should be false", "false", result.getResource(0).getContent().toString());
result = queryResource(service, "numbers.xml", "boolean(('Hello'))", 1);
assertEquals("boolean value of sequence with non-empty string should be true",
"true", result.getResource(0).getContent().toString());
// result = queryResource(service, "numbers.xml", "boolean((0.0, 0.0))", 1);
// assertEquals("boolean value of sequence with two elements should be true", "true",
// result.getResource(0).getContent());
result = queryResource(service, "numbers.xml", "boolean(//item[@id = '1']/price)", 1);
assertEquals("boolean value of 5.6 should be true", "true",
result.getResource(0).getContent().toString());
String message = "";
try {
queryResource(service, "numbers.xml", "boolean(current-time())", 1);
} catch (XMLDBException e) {
message = e.getMessage();
}
assertTrue(message.indexOf("FORG0006") > -1);
}
@Test
public void not() throws XMLDBException {
final XQueryService service =
storeXMLStringAndGetQueryService("strings.xml", strings);
queryResource(service, "strings.xml", "/test/string[not(@value)]", 2);
ResourceSet result = queryResource(service, "strings.xml", "not(/test/abcd)", 1);
Resource r = result.getResource(0);
assertEquals("true", r.getContent().toString());
result = queryResource(service, "strings.xml", "not(/test)", 1);
r = result.getResource(0);
assertEquals("false", r.getContent().toString());
result = queryResource(service, "strings.xml", "/test/string[not(@id)]", 3);
r = result.getResource(0);
assertEquals("<string>Hello World!</string>", r.getContent().toString());
// test with non-existing items
queryResource(service, "strings.xml", "xmldb:document()/blah[not(blah)]", 0);
queryResource(service, "strings.xml", "//*[string][not(@value)]", 1);
queryResource(service, "strings.xml", "//*[string][not(@blah)]", 1);
queryResource(service, "strings.xml", "//*[blah][not(@blah)]", 0);
}
@Test
public void logicalOr() throws XMLDBException, IOException, SAXException {
final XQueryService service =
storeXMLStringAndGetQueryService("strings.xml", strings);
ResourceSet result = queryResource(service, "strings.xml", "<test>{() or ()}</test>", 1);
Resource r = result.getResource(0);
assertXMLEqual("<test>false</test>", r.getContent().toString());
result = queryResource(service, "strings.xml", "() or ()", 1);
r = result.getResource(0);
assertEquals("false", r.getContent().toString());
}
@Test
public void logicalAnd() throws XMLDBException, IOException, SAXException {
final XQueryService service =
storeXMLStringAndGetQueryService("strings.xml", strings);
ResourceSet result = queryResource(service, "strings.xml", "<test>{() and ()}</test>", 1);
Resource r = result.getResource(0);
assertXMLEqual("<test>false</test>", r.getContent().toString());
result = queryResource(service, "strings.xml", "() and ()", 1);
r = result.getResource(0);
assertEquals("false", r.getContent().toString());
}
@Test
public void ids() throws XMLDBException {
final XQueryService service =
storeXMLStringAndGetQueryService("ids.xml", ids);
queryResource(service, "ids.xml", "//a/id(@ref)", 1);
queryResource(service, "ids.xml", "/test/id(//a/@ref)", 1);
ResourceSet result = queryResource(service, "ids.xml", "//a/id(@ref)/name", 1);
Resource r = result.getResource(0);
assertEquals("<name>one</name>", r.getContent().toString());
result = queryResource(service, "ids.xml", "//d/id(@ref)/name", 1);
r = result.getResource(0);
assertEquals("<name>two</name>", r.getContent().toString());
String update = "update insert <t xml:id=\"id3\">Hello</t> into /test";
queryResource(service, "ids.xml", update, 0);
queryResource(service, "ids.xml", "/test/id('id3')", 1);
update = "update value //t/@xml:id with 'id4'";
queryResource(service, "ids.xml", update, 0);
queryResource(service, "ids.xml", "id('id4', /test)", 1);
}
@Test
public void idsOnEmptyCollection() throws XMLDBException {
final Collection root = DatabaseManager.getCollection(uri, "admin", null);
final CollectionManagementService service = (CollectionManagementService) root.getService("CollectionManagementService", "1.0");
final Collection emptyCollection = service.createCollection("empty");
final XQueryService queryService = (XQueryService) emptyCollection.getService("XPathQueryService", "1.0");
queryAndAssert(queryService, "/*", 0, null);
queryAndAssert(queryService, "/id('foo')", 0, null);
}
@Test
public void idRefs() throws XMLDBException {
final XQueryService service =
storeXMLStringAndGetQueryService("ids.xml", ids);
queryResource(service, "ids.xml", "/idref('id2')", 1);
queryResource(service, "ids.xml", "/idref('id1')", 2);
queryResource(service, "ids.xml", "/idref(('id2', 'id1'))", 3);
queryResource(service, "ids.xml", "<results>{/idref('id2')}</results>", 1);
}
@Test
public void externalVars() throws XMLDBException {
XQueryService service =
storeXMLStringAndGetQueryService("strings.xml", strings);
String query =
"declare variable $x external;" +
"$x";
CompiledExpression expr = service.compile(query);
//Do not declare the variable...
boolean exceptionThrown = false;
try {
service.execute(expr);
} catch (XMLDBException e) {
exceptionThrown = true;
}
assertTrue("Expected XPTY0002", exceptionThrown);
query =
"declare variable $local:string external;" +
"/test/string[. = $local:string]";
expr = service.compile(query);
service.declareVariable("local:string", "Hello");
ResourceSet result = service.execute(expr);
final XMLResource r = (XMLResource) result.getResource(0);
Node node = r.getContentAsDOM();
if (node.getNodeType() == Node.DOCUMENT_NODE) {
node = node.getFirstChild();
}
assertEquals("string", node.getNodeName());
//Instanciate a new service to prevent variable reuse
//TODO : consider auto-reset ?
service = storeXMLStringAndGetQueryService("strings.xml", strings);
query =
"declare variable $local:string as xs:string external;" +
"$local:string";
expr = service.compile(query);
//TODO : we should virtually pass any kind of value
service.declareVariable("local:string", new Integer(1));
String message = "";
try {
service.execute(expr);
System.out.println(query);
} catch (XMLDBException e) {
e.printStackTrace();
message = e.getMessage();
}
assertTrue(message.indexOf("XPTY0004") > -1);
service = storeXMLStringAndGetQueryService("strings.xml", strings);
query =
"declare variable $x as xs:integer external; " +
"$x";
expr = service.compile(query);
//TODO : we should virtually pass any kind of value
service.declareVariable("x", "1");
message = "";
try {
System.out.println(query);
service.execute(expr);
} catch (XMLDBException e) {
e.printStackTrace();
message = e.getMessage();
}
assertTrue(message.indexOf("XPTY0004") > -1);
}
@Test
public void externalVars2() throws ParserConfigurationException, IOException, SAXException, XMLDBException {
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
final DocumentBuilder builder = factory.newDocumentBuilder();
final InputSource source = new InputSource(new StringReader(strings));
final Document doc = builder.parse(source);
final XQueryService service = (XQueryService) testCollection.getService("XQueryService", "1.0");
final CompiledExpression expr = service.compile("declare variable $local:node external; $local:node//string");
service.declareVariable("local:node", doc.getDocumentElement());
final ResourceSet result = service.execute(expr);
assertEquals(3, result.getSize());
}
@Test
public void queryResource() throws XMLDBException {
XMLResource doc =
(XMLResource) testCollection.createResource("strings.xml", "XMLResource");
doc.setContent(strings);
testCollection.storeResource(doc);
doc = (XMLResource) testCollection.createResource("strings2.xml", "XMLResource");
doc.setContent(strings);
testCollection.storeResource(doc);
final XPathQueryService query =
(XPathQueryService) testCollection.getService(
"XPathQueryService",
"1.0");
ResourceSet result = query.queryResource("strings2.xml", "/test/string[. = 'Hello World!']");
assertEquals(1, result.getSize());
result = query.query("/test/string[. = 'Hello World!']");
assertEquals(2, result.getSize());
}
/**
* test involving ancestor::
* >>>>>>> currently this produces variable corruption :
* The result is the ancestor <<<<<<<<<<
*/
@Test
public void ancestor() throws XMLDBException {
final XQueryService service =
storeXMLStringAndGetQueryService("numbers.xml", numbers);
final String query =
"let $all_items := /test/item " +
"(: Note: variable non used but computed anyway :)" +
"let $unused_variable :=" +
" for $one_item in $all_items " +
" / ancestor::* (: <<<<< if you remove this line all is normal :)" +
" return 'foo'" +
"return $all_items";
final ResourceSet result = service.queryResource("numbers.xml", query );
assertEquals(4, result.getSize());
}
@Test
public void namespaces() throws XMLDBException {
final XQueryService service =
storeXMLStringAndGetQueryService("namespaces.xml", namespaces);
service.setNamespace("t", "http://www.foo.com");
service.setNamespace("c", "http://www.other.com");
ResourceSet result =
service.queryResource("namespaces.xml", "//t:section");
assertEquals(1, result.getSize());
result =
service.queryResource("namespaces.xml", "/t:test//c:comment");
assertEquals(1, result.getSize());
result = service.queryResource("namespaces.xml", "//c:*");
assertEquals(1, result.getSize());
result = service.queryResource("namespaces.xml", "//*:comment");
assertEquals(1, result.getSize());
result = service.queryResource("namespaces.xml", "namespace-uri(//t:test)");
assertEquals(1, result.getSize());
assertEquals("http://www.foo.com", result.getResource(0).getContent().toString());
}
@Test
public void preserveSpace() throws XMLDBException, IOException, SAXException {
final XQueryService service =
storeXMLStringAndGetQueryService("whitespace.xml", ws);
final ResourceSet result =
service.queryResource("whitespace.xml", "//text");
assertEquals(2, result.getSize());
String item = result.getResource(0).getContent().toString();
assertXMLEqual("<text> </text>", item);
item = result.getResource(1).getContent().toString();
assertXMLEqual("<text xml:space=\"default\"/>", item);
}
@Test
public void nestedElements() throws XMLDBException {
final XQueryService service =
storeXMLStringAndGetQueryService("nested.xml", nested);
final ResourceSet result = service.queryResource("nested.xml", "//c");
printResult(result);
assertEquals(3, result.getSize());
}
@Test
public void staticVariables() throws XMLDBException {
final XMLResource doc =
(XMLResource) testCollection.createResource(
"numbers.xml", "XMLResource" );
doc.setContent(numbers);
testCollection.storeResource(doc);
XPathQueryService service =
(XPathQueryService) testCollection.getService(
"XPathQueryService",
"1.0");
final XPathQueryServiceImpl service2 = (XPathQueryServiceImpl) service;
service2.declareVariable("name", "MONTAGUE");
service2.declareVariable("name", "43");
//ResourceSet result = service.query("//SPEECH[SPEAKER=$name]");
ResourceSet result = service2.query( doc, "//item[stock=$name]");
System.out.println("testStaticVariables 1: ========");
printResult(result);
result = service2.query("$name");
assertEquals(1, result.getSize());
System.out.println("testStaticVariables 2: ========");
printResult(result);
result = service2.query( doc, "//item[stock=43]");
assertEquals(1, result.getSize());
System.out.println("testStaticVariables 3: ========");
printResult(result);
result = service2.query(doc, "//item");
assertEquals(4, result.getSize());
// assertEquals(10, result.getSize());
}
@Test
public void membersAsResource() throws XMLDBException, IOException {
// XPathQueryService service =
// (XPathQueryService) testCollection.getService(
// "XPathQueryService",
// "1.0");
// ResourceSet result = service.query("//SPEECH[LINE &= 'marriage']");
final XQueryService service =
storeXMLStringAndGetQueryService("numbers.xml", numbers);
final ResourceSet result = service.query("//item/price");
final Resource r = result.getMembersAsResource();
final Object rawContent = r.getContent();
String content = null;
if(rawContent instanceof File) {
final FileInputStream fis = new FileInputStream((File)rawContent);
final ByteArrayOutputStream bos = new ByteArrayOutputStream(2048);
byte[] temp = new byte[1024];
int count = 0;
while((count = fis.read(temp)) > -1) {
bos.write(temp, 0, count);
}
content = new String(bos.toByteArray(),UTF_8);
} else {
content = (String)r.getContent();
}
System.out.println(content);
final Pattern p = Pattern.compile(".*(<price>.*){4}", Pattern.DOTALL);
final Matcher m = p.matcher(content);
assertTrue("get whole document numbers.xml", m.matches());
}
@Test
public void satisfies() throws XMLDBException {
final XQueryService service = getQueryService();
ResourceSet result = queryAndAssert(service,
"every $foo in (1,2,3) satisfies" +
" let $bar := 'baz'" +
" return false() ",
1, "");
assertEquals("satisfies + FLWR expression allways false 1", "false", result.getResource(0).getContent().toString());
result = queryAndAssert(service,
"declare function local:foo() { false() };" +
" every $bar in (1,2,3) satisfies" +
" local:foo()",
1, "");
assertEquals("satisfies + FLWR expression allways false 2", "false", result.getResource(0).getContent().toString());
String query = "every $x in () satisfies false()";
result = queryAndAssert(service, query, 1, "");
assertEquals(query, "true", result.getResource(0).getContent().toString());
query = "some $x in () satisfies true()";
result = queryAndAssert(service, query, 1, "");
assertEquals(query, "false", result.getResource(0).getContent().toString());
}
@Test
public void intersect() throws XMLDBException {
final XQueryService service = getQueryService();
String query = "() intersect ()";
queryAndAssert(service, query, 0, "");
query = "() intersect (1)";
queryAndAssert(service, query, 0, "");
query = "(1) intersect ()";
queryAndAssert(service, query, 0, "");
}
@Test
public void union() throws XMLDBException {
final XQueryService service = getQueryService();
String query = "() union ()";
queryAndAssert( service, query, 0, "");
String message = "";
try {
query = "() union (1)";
queryAndAssert( service, query, 0, "");
} catch (XMLDBException e) {
message = e.getMessage();
}
assertTrue(message.indexOf("XPTY0004") > -1);
message = "";
try {
query = "(1) union ()";
queryAndAssert(service, query, 0, "");
} catch (XMLDBException e) {
message = e.getMessage();
}
assertTrue(message.indexOf("XPTY0004") > -1);
query = "<a/> union ()";
queryAndAssert(service, query, 1, "");
query = "() union <a/>";
queryAndAssert(service, query, 1, "");
//Not the same nodes
query = "<a/> union <a/>";
queryAndAssert(service, query, 2, "");
}
@Test
public void except() throws XMLDBException {
final XQueryService service = getQueryService();
String query = "() except ()";
queryAndAssert(service, query, 0, "");
query = "() except (1)";
queryAndAssert(service, query, 0, "");
String message = "";
try {
query = "(1) except ()";
queryAndAssert(service, query, 0, "");
} catch (XMLDBException e) {
message = e.getMessage();
}
assertTrue(message.indexOf("XPTY0004") > -1);
query = "<a/> except ()";
queryAndAssert(service, query, 1, "");
query = "() except <a/>";
queryAndAssert(service, query, 0, "");
//Not the same nodes
query = "<a/> except <a/>";
queryAndAssert(service, query, 1, "");
}
@Test
public void convertToBoolean() throws XMLDBException {
final XQueryService service = getQueryService();
ResourceSet result = queryAndAssert(
service,
"let $doc := <element attribute=''/>" + "return ("
+ " <true>{boolean(($doc,2,3))}</true> ,"
+ " <true>{boolean(($doc/@*,2,3))}</true> ,"
+ " <true>{boolean(true())}</true> ,"
+ " <true>{boolean('test')}</true> ,"
+ " <true>{boolean(number(1))}</true> ,"
+ " <false>{boolean((0))}</false> ,"
+ " <false>{boolean(false())}</false> ,"
+ " <false>{boolean('')}</false> ,"
+ " <false>{boolean(number(0))}</false> ,"
+ " <false>{boolean(number('NaN'))}</false>" + ")",
10, "");
for (int i = 0; i < 10; i++) {
if(i < 5) {
assertEquals("true " + (i + 1), "<true>true</true>", result
.getResource(i).getContent().toString());
} else {
assertEquals("false " + (i + 1), "<false>false</false>", result
.getResource(i).getContent().toString());
}
}
boolean exceptionThrown = false;
String message = "";
try {
queryAndAssert(service,
"let $doc := <element attribute=''/>"
+ " return boolean( (1,2,$doc) )", 1, "");
} catch (XMLDBException e) {
exceptionThrown = true;
message = e.getMessage();
}
assertTrue("Exception wanted: " + message, exceptionThrown);
}
@Test
public void compile() throws XMLDBException {
final String invalidQuery = "for $i in (1 to 10)\n return $b";
final String validQuery = "for $i in (1 to 10) return $i";
final String validModule = "module namespace foo=\"urn:foo\";\n" +
"declare function foo:test() { \"Hello World!\" };";
final String invalidModule = "module namespace foo=\"urn:foo\";\n" +
"declare function foo:test() { \"Hello World! };";
final org.exist.xmldb.XQueryService service = (org.exist.xmldb.XQueryService) getQueryService();
boolean exceptionOccurred = false;
try {
service.compile(invalidQuery);
} catch (XMLDBException e) {
assertEquals(((XPathException)e.getCause()).getLine(), 2);
exceptionOccurred = true;
}
assertTrue("Expected an exception", exceptionOccurred);
exceptionOccurred = false;
try {
service.compileAndCheck(invalidModule);
} catch (XPathException e) {
exceptionOccurred = true;
}
assertTrue("Expected an exception", exceptionOccurred);
service.compile(validQuery);
service.compile(validModule);
}
/**
* Added by Geoff Shuetrim on 15 July 2006 (geoff@galexy.net).
* This test has been added following identification of a problem running
* XPath queries that involved the name of elements with the name 'xpointer'.
* @throws XMLDBException
*/
@Ignore
@Test
public void xpointerElementNameHandling() throws XMLDBException {
final XQueryService service = storeXMLStringAndGetQueryService(
"xpointer.xml", xpointerElementName);
ResourceSet result = service.queryResource("xpointer.xml",
"/test/.[local-name()='xpointer']");
printResult(result);
assertEquals(1, result.getSize());
result = service.queryResource("xpointer.xml", "/test/xpointer");
printResult(result);
assertEquals(1, result.getSize());
}
@Test
public void atomization() throws XMLDBException, IOException, SAXException {
final String query =
"declare namespace ex = \"http://example.org\";\n" +
"declare function ex:elementName() as xs:QName {\n" +
" QName(\"http://test.org\", \"test:name\")\n" +
"};\n" +
"<test>{\n" +
" element {QName(\"http://test.org\", \"test:name\") }{},\n" +
" element {ex:elementName()} {}\n" +
"}</test>";
final org.exist.xmldb.XQueryService service = (org.exist.xmldb.XQueryService)getQueryService();
service.setProperty(OutputKeys.INDENT, "no");
final ResourceSet result = service.query(query);
assertEquals(1, result.getSize());
printResult(result);
assertXMLEqual("<test><test:name xmlns:test=\"http://test.org\"/><test:name xmlns:test=\"http://test.org\"/></test>", result.getResource(0).getContent().toString());
}
@Test
public void substring() throws XMLDBException {
final XQueryService service = getQueryService();
// Testcases by MIKA
final String validQuery = "substring(\"MK-1234\", 4,1)";
ResourceSet result = queryAndAssert( service, validQuery, 1, validQuery);
assertEquals("1", result.getResource(0).getContent().toString());
String invalidQuery = "substring(\"MK-1234\", 4,4)";
result = queryAndAssert( service, invalidQuery, 1, invalidQuery);
assertEquals("1234", result.getResource(0).getContent().toString());
// Testcase by Toar
final String toarQuery="let $num := \"2003.123\" \n return substring($num, 1, 7)";
result = queryAndAssert( service, toarQuery, 1, toarQuery);
assertEquals("2003.12", result.getResource(0).getContent().toString());
}
/**
* Helper that performs an XQuery and does JUnit assertion on result size.
*
* @see #queryResource(XQueryService, String, String, int, String)
*/
private ResourceSet queryResource(final XQueryService service, final String resource,
final String query, final int expected) throws XMLDBException {
return queryResource(service, resource, query, expected, null);
}
/**
* Helper that performs an XQuery and does JUnit assertion on result size.
*
* @param service XQuery service
* @param resource database resource (collection) to query
* @param query
* @param expected size of result
* @param message for JUnit
*
* @return a ResourceSet, allowing to do more assertions if necessary.
* @throws XMLDBException
*/
private ResourceSet queryResource(final XQueryService service, final String resource,
final String query, final int expected, final String message) throws XMLDBException {
final ResourceSet result = service.queryResource(resource, query);
if(message == null) {
assertEquals(query, expected, result.getSize());
} else {
assertEquals(message, expected, result.getSize());
}
return result;
}
/** For queries without associated data */
private ResourceSet queryAndAssert(final XQueryService service, final String query,
final int expected, final String message) throws XMLDBException {
final ResourceSet result = service.query(query);
if(message == null) {
assertEquals(expected, result.getSize());
} else {
assertEquals(message, expected, result.getSize());
}
return result;
}
/** For queries without associated data */
private XQueryService getQueryService() throws XMLDBException {
final XQueryService service = (XQueryService) testCollection.getService(
"XPathQueryService", "1.0");
return service;
}
/** stores XML String and get Query Service
* @param documentName to be stored in the DB
* @param content to be stored in the DB
* @return the XQuery Service
* @throws XMLDBException
*/
private XQueryService storeXMLStringAndGetQueryService(final String documentName,
final String content) throws XMLDBException {
final XMLResource doc =
(XMLResource) testCollection.createResource(
documentName, "XMLResource" );
doc.setContent(content);
testCollection.storeResource(doc);
final XQueryService service =
(XQueryService) testCollection.getService(
"XPathQueryService",
"1.0");
return service;
}
/**
* @param result
* @throws XMLDBException
*/
private void printResult(final ResourceSet result) throws XMLDBException {
for (final ResourceIterator i = result.getIterator(); i.hasMoreResources(); ) {
final Resource r = i.nextResource();
System.out.println(r.getContent());
}
}
public static void main(final String[] args) {
JUnitCore.runClasses(XPathQueryTest.class);
}
}