vgritsenko 2004/02/24 07:44:01
Modified: java/tests/src/org/apache/xindice/integration/client/services XPathQueryTest.java java/src/org/apache/xindice/core/query QueryUtil.java . status.xml Log: XPath query resulting in attribute nodes will return attributes on the <result> element. Revision Changes Path 1.12 +425 -530 xml-xindice/java/tests/src/org/apache/xindice/integration/client/services/XPathQueryTest.java Index: XPathQueryTest.java =================================================================== RCS file: /home/cvs/xml-xindice/java/tests/src/org/apache/xindice/integration/client/services/XPathQueryTest.java,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- XPathQueryTest.java 8 Feb 2004 03:57:02 -0000 1.11 +++ XPathQueryTest.java 24 Feb 2004 15:44:01 -0000 1.12 @@ -20,545 +20,440 @@ import org.apache.xindice.integration.client.AbstractXmlDbClientTest; import org.apache.xindice.xml.TextWriter; -import org.custommonkey.xmlunit.XMLAssert; +import org.custommonkey.xmlunit.XMLAssert; import org.w3c.dom.Node; +import org.w3c.dom.Document; import org.xmldb.api.base.Collection; -import org.xmldb.api.base.ResourceIterator; import org.xmldb.api.base.ResourceSet; import org.xmldb.api.base.XMLDBException; import org.xmldb.api.modules.XMLResource; import org.xmldb.api.modules.XPathQueryService; -import java.util.ArrayList; -import java.util.List; - /** - * @version CVS $Revision$, $Date$ - * @author Vladimir R. Bossicard <[EMAIL PROTECTED]> + * + * @author <a href="mailto:[EMAIL PROTECTED]">Vladimir R. Bossicard</a> * @author <a href="mailto:[EMAIL PROTECTED]">Kevin O'Neill</a> + * @version CVS $Revision$, $Date$ */ -public class XPathQueryTest extends AbstractXmlDbClientTest -{ +public class XPathQueryTest extends AbstractXmlDbClientTest { + + private Collection col; + private XPathQueryService xpathservice; + + public void setUp() throws Exception { + super.setUp(); - public void setUp() throws Exception - { - super.setUp(); - - String document1 = - "<?xml version=\"1.0\"?>" - + "<person>" - + "<first>John</first>" - + "<last>Smith</last>" - + "<age>30</age>" - + "<phone type=\"work\">555-345-6789</phone>" - + "</person>"; - String document2 = - "<?xml version=\"1.0\"?>" - + "<person>" - + "<first>Sally</first>" - + "<last>Smith</last>" - + "<age>20</age>" - + "<phone type=\"work\">555-345-6789</phone>" - + "</person>"; - - this.client.insertDocument(TEST_COLLECTION_PATH, "doc1", document1); - this.client.insertDocument(TEST_COLLECTION_PATH, "doc2", document2); - } - - public void tearDown() throws Exception - { - this.client.removeDocument(TEST_COLLECTION_PATH, "doc1"); - this.client.removeDocument(TEST_COLLECTION_PATH, "doc2"); - - super.tearDown(); - } - - public void testSimpleQuery() throws Exception - { - String query = "//person[last='Smith']"; - - Collection col = this.client.getCollection(TEST_COLLECTION_PATH); - XPathQueryService xpathservice = (XPathQueryService) col.getService("XPathQueryService", "1.0"); - ResourceSet resultSet = xpathservice.query(query); - - ResourceIterator results = resultSet.getIterator(); - - List res = asList(results); - assertEquals(2, res.size()); - } - - public void testSimpleAndQuery() throws Exception - { - String query = "//person[first='John' and last='Smith']"; - - Collection col = this.client.getCollection(TEST_COLLECTION_PATH); - XPathQueryService xpathservice = (XPathQueryService) col.getService("XPathQueryService", "1.0"); - ResourceSet resultSet = xpathservice.query(query); - - ResourceIterator results = resultSet.getIterator(); - - List res = asList(results); - assertEquals(1, res.size()); - } - - public void testSimpleOrQuery() throws Exception - { - String query = "//person[first='John' or last='Smith']"; - - Collection col = this.client.getCollection(TEST_COLLECTION_PATH); - XPathQueryService xpathservice = (XPathQueryService) col.getService("XPathQueryService", "1.0"); - ResourceSet resultSet = xpathservice.query(query); - - ResourceIterator results = resultSet.getIterator(); - - List res = asList(results); - assertEquals(2, res.size()); - } - - public void testMultipleOrQuery() throws Exception - { - String query = "//person[first='John' or first='Sally']"; - - Collection col = this.client.getCollection(TEST_COLLECTION_PATH); - XPathQueryService xpathservice = (XPathQueryService) col.getService("XPathQueryService", "1.0"); - ResourceSet resultSet = xpathservice.query(query); - - ResourceIterator results = resultSet.getIterator(); - - List res = asList(results); - assertEquals(2, res.size()); - } - - public void testAndOrQuery() throws Exception - { - String query = "//person[last='Smith' and (first='John' or first='Sally')]"; - - Collection col = this.client.getCollection(TEST_COLLECTION_PATH); - XPathQueryService xpathservice = (XPathQueryService) col.getService("XPathQueryService", "1.0"); - ResourceSet resultSet = xpathservice.query(query); - - ResourceIterator results = resultSet.getIterator(); - - List res = asList(results); - assertEquals(2, res.size()); - } - - public void testSimpleWildcardSearchQuery() throws Exception - { - // search all records whose last name contains 'Smi' - String query = "//person[contains(last, 'Smi')]"; - - Collection col = this.client.getCollection(TEST_COLLECTION_PATH); - XPathQueryService xpathservice = (XPathQueryService) col.getService("XPathQueryService", "1.0"); - ResourceSet resultSet = xpathservice.query(query); - - ResourceIterator results = resultSet.getIterator(); - List res = asList(results); - assertEquals(2, res.size()); - } - - public void testStartsWithSearchQuery() throws Exception - { - String document3 = - "<?xml version=\"1.0\"?>" - + "<person>" - + "<first>Sally</first>" - + "<last>aSm</last>" - + "<phone type=\"work\">555-345-6789</phone>" - + "</person>"; - this.client.insertDocument(TEST_COLLECTION_PATH, "doc3", document3); - - // search all records whose last name begins with 'Smi' - String query = "//person[(string-length(//person/last) >= 3) and (substring(//person/last, 1, 3)='Smi')]"; - - Collection col = this.client.getCollection(TEST_COLLECTION_PATH); - XPathQueryService xpathservice = (XPathQueryService) col.getService("XPathQueryService", "1.0"); - ResourceSet resultSet = xpathservice.query(query); - - ResourceIterator results = resultSet.getIterator(); - List res = asList(results); - assertEquals(2, res.size()); - - this.client.removeDocument(TEST_COLLECTION_PATH, "doc3"); - } - - public void testEndsWithSearchQuery() throws Exception - { - // search all records whose last name begins with 'ith' - String query = "//person[(string-length(//person/last) >= 4) and (substring(//person/last, 2)='mith')]"; - - Collection col = this.client.getCollection(TEST_COLLECTION_PATH); - XPathQueryService xpathservice = (XPathQueryService) col.getService("XPathQueryService", "1.0"); - ResourceSet resultSet = xpathservice.query(query); - - ResourceIterator results = resultSet.getIterator(); - List res = asList(results); - assertEquals(2, res.size()); - } - - public void testGreaterSearchQuery() throws Exception - { - String query = "//person[age > 25]"; - - Collection col = this.client.getCollection(TEST_COLLECTION_PATH); - XPathQueryService xpathservice = (XPathQueryService) col.getService("XPathQueryService", "1.0"); - ResourceSet resultSet = xpathservice.query(query); - - ResourceIterator results = resultSet.getIterator(); - List res = asList(results); - assertEquals(1, res.size()); - } - - public void testGetSingleTextNode() throws Exception - { - String query = "//person[first='John' and last='Smith']/first/text()"; - - Collection col = this.client.getCollection(TEST_COLLECTION_PATH); - XPathQueryService xpathservice = (XPathQueryService) col.getService("XPathQueryService", "1.0"); - ResourceSet resultSet = xpathservice.query(query); - - assertEquals(1L, resultSet.getSize()); - assertEquals("John", resultSet.getResource(0).getContent()); - } - - public void testGetMultipleTextNodes() throws Exception - { - String query = "//person/first/text()"; - - Collection col = this.client.getCollection(TEST_COLLECTION_PATH); - XPathQueryService xpathservice = (XPathQueryService) col.getService("XPathQueryService", "1.0"); - ResourceSet resultSet = xpathservice.query(query); - - ResourceIterator results = resultSet.getIterator(); - - List res = asList(results); - assertEquals(2, res.size()); - } - - public void testNamespaceDOM() throws Exception - { - String document3 = - "<?xml version=\"1.0\"?>" - + "<p:person xmlns:p='http://example.net/person' >" - + "<p:first>Sally</p:first>" - + "<p:last>Smith</p:last>" - + "<p:phone type=\"work\">555-345-6789</p:phone>" - + "</p:person>"; - this.client.insertDocument(TEST_COLLECTION_PATH, "doc3", document3); - - String query = "//h:person[h:first='Sally' and h:last='Smith']/h:first"; - - Collection col = this.client.getCollection(TEST_COLLECTION_PATH); - XPathQueryService xpathservice = (XPathQueryService) col.getService("XPathQueryService", "1.0"); - xpathservice.setNamespace("h", "http://example.net/person"); - - ResourceSet resultSet = xpathservice.query(query); - - ResourceIterator results = resultSet.getIterator(); - List res = asList(results); - assertEquals(1, res.size()); - - XMLResource resource = (XMLResource) resultSet.getResource(0); - - // ensure that the resource has the correct doc id. - assertEquals("doc3", resource.getDocumentId()); - - Node node = resource.getContentAsDOM(); - - // add source node information to the compared xml as it's added by - // the query processor. - XMLAssert.assertXMLEqual( - "<first xmlns:src='http://xml.apache.org/xindice/Query' src:col='/db/testing/current' src:key='doc3' xmlns='http://example.net/person'>Sally</first>", - TextWriter.toString(node)); - - this.client.removeDocument(TEST_COLLECTION_PATH, "doc3"); - } - - public void testFetchMultipleAttributeNode() throws Exception - { - String document3 = "<?xml version=\"1.0\"?>" + "<foo bar='foo'>" + "<bar foo='bar' bar='bar'/>" + "</foo>"; - - client.insertDocument(TEST_COLLECTION_PATH, "doc3", document3); - - String query = "//@bar"; - - Collection col = this.client.getCollection(TEST_COLLECTION_PATH); - XPathQueryService xpathservice = (XPathQueryService) col.getService("XPathQueryService", "1.0"); - - ResourceSet resultSet = null; - try - { - resultSet = xpathservice.query(query); - } - catch (Exception e) - { - fail(e.getMessage()); - } - - ResourceIterator results = resultSet.getIterator(); - List res = asList(results); - assertEquals(2, res.size()); - - XMLResource resource = (XMLResource) resultSet.getResource(0); - - Node node = resource.getContentAsDOM(); - - client.removeDocument(TEST_COLLECTION_PATH, "doc3"); - } - - public void testFetchAttributeNode() throws Exception - { - String document3 = "<?xml version=\"1.0\"?>" + "<foo bar='foo'>" + "<bar foo='bar' bar='bar'/>" + "</foo>"; - - client.insertDocument(TEST_COLLECTION_PATH, "doc3", document3); - - String query = "//foo/@bar"; - - Collection col = this.client.getCollection(TEST_COLLECTION_PATH); - XPathQueryService xpathservice = (XPathQueryService) col.getService("XPathQueryService", "1.0"); - - ResourceSet resultSet = null; - try - { - resultSet = xpathservice.query(query); - } - catch (Exception e) - { - fail(e.getMessage()); - } - - assertEquals(1L, resultSet.getSize()); - assertEquals("foo", resultSet.getResource(0).getContent().toString()); - } - - public void testFetchBoolean() throws Exception - { - String query = "boolean(//person)"; - - Collection col = client.getCollection(TEST_COLLECTION_PATH); - XPathQueryService xpathservice = (XPathQueryService) col.getService("XPathQueryService", "1.0"); - try - { - ResourceSet resultSet = xpathservice.query(query); - - // when we do support it the following tests will be run - assertEquals(2L, resultSet.getSize()); - assertEquals("true", resultSet.getResource(1L).getContent()); - - } - catch (XMLDBException e) - { - fail(e.getMessage()); - } - } - - public void testFetchString() throws Exception - { - String query = "string(//person[first='John' and last='Smith']/first)"; - - Collection col = client.getCollection(TEST_COLLECTION_PATH); - XPathQueryService xpathservice = (XPathQueryService) col.getService("XPathQueryService", "1.0"); - try - { - ResourceSet resultSet = xpathservice.query(query); - - assertEquals(2L, resultSet.getSize()); - } - catch (XMLDBException e) - { - fail(e.getMessage()); - } - } - - public void testFetchNumber() throws Exception - { - String query = "count(//person[first='John' and last='Smith'])"; - - Collection col = client.getCollection(TEST_COLLECTION_PATH); - XPathQueryService xpathservice = (XPathQueryService) col.getService("XPathQueryService", "1.0"); - try - { - ResourceSet resultSet = xpathservice.query(query); - - assertEquals(2L, resultSet.getSize()); - } - catch (XMLDBException e) - { - fail(e.getMessage()); - } - } - - public void testSrcAddedToRootOnly() throws Exception - { - String query = "//person[first='John' and last='Smith']"; - - Collection col = this.client.getCollection(TEST_COLLECTION_PATH); - XPathQueryService xpathservice = (XPathQueryService) col.getService("XPathQueryService", "1.0"); - ResourceSet resultSet = xpathservice.query(query); - - ResourceIterator results = resultSet.getIterator(); - - List res = asList(results); - assertEquals(1, res.size()); - - XMLResource resource = (XMLResource) resultSet.getResource(0); - - String john = - "<?xml version=\"1.0\"?>" - + "<person xmlns:src='http://xml.apache.org/xindice/Query' src:col='/db/testing/current' src:key='doc1'>" - + "<first>John</first>" - + "<last>Smith</last>" - + "<age>30</age>" - + "<phone type=\"work\">555-345-6789</phone>" - + "</person>"; - - // ensure that the resource has the correct doc id. - assertEquals("doc1", resource.getDocumentId()); - - XMLAssert.assertXMLEqual(john, TextWriter.toString(resource.getContentAsDOM())); - } - - public void testConflictingPrefix() throws Exception - { - String document3 = - "<?xml version=\"1.0\"?>" - + "<src:person xmlns:src='http://example.net/person' >" - + "<src:first>Sally</src:first>" - + "<src:last>Smith</src:last>" - + "<src:phone type=\"work\">555-345-6789</src:phone>" - + "</src:person>"; - this.client.insertDocument(TEST_COLLECTION_PATH, "doc3", document3); - - String query = "//h:person[h:first='Sally' and h:last='Smith']/h:first"; - - Collection col = this.client.getCollection(TEST_COLLECTION_PATH); - XPathQueryService xpathservice = (XPathQueryService) col.getService("XPathQueryService", "1.0"); - xpathservice.setNamespace("h", "http://example.net/person"); - - ResourceSet resultSet = xpathservice.query(query); - - ResourceIterator results = resultSet.getIterator(); - List res = asList(results); - assertEquals(1, res.size()); - - XMLResource resource = (XMLResource) resultSet.getResource(0); - - // ensure that the resource has the correct doc id. - assertEquals("doc3", resource.getDocumentId()); - - Node node = resource.getContentAsDOM(); - - // add source node information to the compared xml as it's added by - // the query processor. - XMLAssert.assertXMLEqual( - "<first xmlns:src='http://xml.apache.org/xindice/Query' src:col='/db/testing/current' src:key='doc3' xmlns='http://example.net/person'>Sally</first>", - TextWriter.toString(node)); - - this.client.removeDocument(TEST_COLLECTION_PATH, "doc3"); - } - - public static List asList(ResourceIterator iter) throws Exception - { - if (iter == null) - { - return null; - } - - List result = null; - result = new ArrayList(); - while (iter.hasMoreResources()) - { - result.add(iter.nextResource()); - } - return result; - } - - public void testNamespacesNotImportedDeep() throws Exception - { - // make sure that we don't have the namespace defs needlessly - // imported from the root all the way through the tree - // i.e. namespaces imported from above root should not - // be spread into child nodes - String document3 = - "<?xml version=\"1.0\"?>" - + "<p:person xmlns:p='http://example.net/person' >" - + "<p:first>Sally</p:first>" - + "<p:last>Smith</p:last>" - + "<p:phone p:type=\"work\">555-345-6789</p:phone>" - + "</p:person>"; - this.client.insertDocument(TEST_COLLECTION_PATH, "doc3", document3); - - String query = "//h:person[h:first='Sally' and h:last='Smith']"; - - Collection col = this.client.getCollection(TEST_COLLECTION_PATH); - XPathQueryService xpathservice = (XPathQueryService) col.getService("XPathQueryService", "1.0"); - xpathservice.setNamespace("h", "http://example.net/person"); - - ResourceSet resultSet = xpathservice.query(query); - - ResourceIterator results = resultSet.getIterator(); - List res = asList(results); - assertEquals(1, res.size()); - - XMLResource resource = (XMLResource) resultSet.getResource(0); - Node node = resource.getContentAsDOM(); - String retrieved = TextWriter.toString(node); - assertFalse("Namespace definitions imported deep in: " + retrieved, -1 == retrieved.indexOf("<p:first>")); - - // ensure that the resource has the correct doc id. - assertEquals("doc3", resource.getDocumentId()); - - // add source node information to the compared xml as it's added by - // the query processor. Note, this should work using without the - // prefixes in the control document using the default namespace, - // (i.e. xmlns='http://example.net/person') but I couldn't get it to work - // with XMLAssert (and we'return not testing XMLAssert so we just use the prefixes here too) - XMLAssert.assertXMLEqual( - "<p:person xmlns:p='http://example.net/person' xmlns:src='http://xml.apache.org/xindice/Query' src:col='/db/testing/current' src:key='doc3'>" - + "<p:first>Sally</p:first>" - + "<p:last>Smith</p:last>" - + "<p:phone p:type=\"work\">555-345-6789</p:phone>" - + "</p:person>", - TextWriter.toString(node)); - - this.client.removeDocument(TEST_COLLECTION_PATH, "doc3"); - } - - public void testMathOpQuery() throws Exception - { - // force a non-XObject Object to be supplied to evalMathOperation as - // one of its operands - // this works in the buggy version of XPathQueryResolver but only - // because a ClassCastException that cuts short the indexing evaluation - // is caught and ignored forcing a collection scan (if logging WARN, you'll see stack trace) - - String query = "//person[substring(last, string-length(last) - two)='ith']"; - String document3 = - "<?xml version=\"1.0\"?>" - + "<person>" - + "<first>Sally</first>" - + "<last>Smith</last>" - + "<one>1</one>" - + "<two>2.0</two>" - + "<phone call=\"no\" type=\"work\">555-345-6789</phone>" - + "</person>"; - this.client.insertDocument(TEST_COLLECTION_PATH, "doc3", document3); - - try - { - Collection col = this.client.getCollection(TEST_COLLECTION_PATH); - XPathQueryService xpathservice = (XPathQueryService) col.getService("XPathQueryService", "1.0"); - ResourceSet resultSet = xpathservice.query(query); - - ResourceIterator results = resultSet.getIterator(); - - List res = asList(results); - assertEquals(1, res.size()); - } - finally - { - this.client.removeDocument(TEST_COLLECTION_PATH, "doc3"); - } - } + this.col = this.client.getCollection(TEST_COLLECTION_PATH); + this.xpathservice = (XPathQueryService) col.getService("XPathQueryService", "1.0"); + + String document1 + = "<?xml version=\"1.0\"?>" + + "<person>" + + "<first>John</first>" + + "<last>Smith</last>" + + "<age>30</age>" + + "<phone type=\"work\">555-345-6789</phone>" + + "</person>"; + String document2 + = "<?xml version=\"1.0\"?>" + + "<person>" + + "<first>Sally</first>" + + "<last>Smith</last>" + + "<age>20</age>" + + "<phone type=\"work\">555-345-6789</phone>" + + "</person>"; + + this.client.insertDocument(TEST_COLLECTION_PATH, "doc1", document1); + this.client.insertDocument(TEST_COLLECTION_PATH, "doc2", document2); + } + + public void tearDown() throws Exception { + this.client.removeDocument(TEST_COLLECTION_PATH, "doc1"); + this.client.removeDocument(TEST_COLLECTION_PATH, "doc2"); + + super.tearDown(); + } + + + public void testSimpleQuery() throws Exception { + String query = "//person[last='Smith']"; + + ResourceSet resultSet = xpathservice.query(query); + assertEquals(2, resultSet.getSize()); + + Document result0 = (Document)((XMLResource) resultSet.getResource(0)).getContentAsDOM(); + Document result1 = (Document)((XMLResource) resultSet.getResource(1)).getContentAsDOM(); + assertEquals("person", result0.getDocumentElement().getNodeName()); + assertEquals("person", result1.getDocumentElement().getNodeName()); + } + + public void testSimpleAndQuery() throws Exception { + String query = "//person[first='John' and last='Smith']"; + + ResourceSet resultSet = xpathservice.query(query); + assertEquals(1, resultSet.getSize()); + + Document result0 = (Document)((XMLResource) resultSet.getResource(0)).getContentAsDOM(); + assertEquals("person", result0.getDocumentElement().getNodeName()); + } + + public void testSimpleOrQuery() throws Exception { + String query = "//person[first='John' or last='Smith']"; + + ResourceSet resultSet = xpathservice.query(query); + assertEquals(2, resultSet.getSize()); + + Document result0 = (Document)((XMLResource) resultSet.getResource(0)).getContentAsDOM(); + Document result1 = (Document)((XMLResource) resultSet.getResource(1)).getContentAsDOM(); + assertEquals("person", result0.getDocumentElement().getNodeName()); + assertEquals("person", result1.getDocumentElement().getNodeName()); + } + + public void testMultipleOrQuery() throws Exception { + String query = "//person[first='John' or first='Sally' or age]"; + + ResourceSet resultSet = xpathservice.query(query); + assertEquals(2, resultSet.getSize()); + + Document result0 = (Document)((XMLResource) resultSet.getResource(0)).getContentAsDOM(); + Document result1 = (Document)((XMLResource) resultSet.getResource(1)).getContentAsDOM(); + assertEquals("person", result0.getDocumentElement().getNodeName()); + assertEquals("person", result1.getDocumentElement().getNodeName()); + } + + public void testAndOrQuery() throws Exception { + String query = "//person[last='Smith' and (first='John' or first='Sally')]"; + + ResourceSet resultSet = xpathservice.query(query); + assertEquals(2, resultSet.getSize()); + + Document result0 = (Document)((XMLResource) resultSet.getResource(0)).getContentAsDOM(); + Document result1 = (Document)((XMLResource) resultSet.getResource(1)).getContentAsDOM(); + assertEquals("person", result0.getDocumentElement().getNodeName()); + assertEquals("person", result1.getDocumentElement().getNodeName()); + } + + public void testContainsSearchQuery() throws Exception { + // search all records whose last name contains 'Smi' + String query = "//person[contains(last, 'Smi')]"; + + ResourceSet resultSet = xpathservice.query(query); + assertEquals(2, resultSet.getSize()); + + Document result0 = (Document)((XMLResource) resultSet.getResource(0)).getContentAsDOM(); + Document result1 = (Document)((XMLResource) resultSet.getResource(1)).getContentAsDOM(); + assertEquals("person", result0.getDocumentElement().getNodeName()); + assertEquals("person", result1.getDocumentElement().getNodeName()); + } + + public void testStartsWithSearchQuery() throws Exception { + String document3 = + "<?xml version=\"1.0\"?>" + + "<person>" + + "<first>Sally</first>" + + "<last>aSm</last>" + + "<phone type=\"work\">555-345-6789</phone>" + + "</person>"; + this.client.insertDocument(TEST_COLLECTION_PATH, "doc3", document3); + + // search all records whose last name begins with 'Smi' + String query = "//person[string-length(//person/last) >= 3 and substring(//person/last, 1, 3)='Smi']"; + + try { + ResourceSet resultSet = xpathservice.query(query); + assertEquals(2, resultSet.getSize()); + + Document result0 = (Document)((XMLResource) resultSet.getResource(0)).getContentAsDOM(); + Document result1 = (Document)((XMLResource) resultSet.getResource(1)).getContentAsDOM(); + assertEquals("person", result0.getDocumentElement().getNodeName()); + assertEquals("person", result1.getDocumentElement().getNodeName()); + } finally { + this.client.removeDocument(TEST_COLLECTION_PATH, "doc3"); + } + } + + public void testEndsWithSearchQuery() throws Exception { + // search all records whose last name begins with 'ith' + String query = "//person[(string-length(//person/last) >= 4) and (substring(//person/last, 2)='mith')]"; + + ResourceSet resultSet = xpathservice.query(query); + assertEquals(2, resultSet.getSize()); + + Document result0 = (Document)((XMLResource) resultSet.getResource(0)).getContentAsDOM(); + Document result1 = (Document)((XMLResource) resultSet.getResource(1)).getContentAsDOM(); + assertEquals("person", result0.getDocumentElement().getNodeName()); + assertEquals("person", result1.getDocumentElement().getNodeName()); + } + + public void testGreaterSearchQuery() throws Exception { + String query = "//person[age > 25]"; + + ResourceSet resultSet = xpathservice.query(query); + assertEquals(1, resultSet.getSize()); + + Document result0 = (Document)((XMLResource) resultSet.getResource(0)).getContentAsDOM(); + assertEquals("person", result0.getDocumentElement().getNodeName()); + } + + public void testLesserSearchQuery() throws Exception { + String query = "//person[age < 25]"; + + ResourceSet resultSet = xpathservice.query(query); + assertEquals(1, resultSet.getSize()); + + Document result0 = (Document)((XMLResource) resultSet.getResource(0)).getContentAsDOM(); + assertEquals("person", result0.getDocumentElement().getNodeName()); + } + + + public void testNamespaceDOM() throws Exception { + String document3 = + "<?xml version=\"1.0\"?>" + + "<p:person xmlns:p='http://example.net/person' >" + + "<p:first>Sally</p:first>" + + "<p:last>Smith</p:last>" + + "<p:phone type=\"work\">555-345-6789</p:phone>" + + "</p:person>"; + this.client.insertDocument(TEST_COLLECTION_PATH, "doc3", document3); + + String query = "//h:person[h:first='Sally' and h:last='Smith']/h:first"; + + xpathservice.setNamespace("h", "http://example.net/person"); + + ResourceSet resultSet = xpathservice.query(query); + assertEquals(1, resultSet.getSize()); + + XMLResource resource = (XMLResource) resultSet.getResource(0); + + // ensure that the resource has the correct doc id. + assertEquals("doc3", resource.getDocumentId()); + + Node node = resource.getContentAsDOM(); + + // add source node information to the compared xml as it's added by + // the query processor. + XMLAssert.assertXMLEqual("<first xmlns:src='http://xml.apache.org/xindice/Query' src:col='/db/testing/current' src:key='doc3' xmlns='http://example.net/person'>Sally</first>", + TextWriter.toString(node)); + + this.client.removeDocument(TEST_COLLECTION_PATH, "doc3"); + } + + + public void testFetchSingleTextNode() throws Exception { + String query = "//person[first='John' and last='Smith']/first/text()"; + + ResourceSet resultSet = xpathservice.query(query); + assertEquals(1L, resultSet.getSize()); + + assertEquals("John", resultSet.getResource(0).getContent()); + } + + public void testFetchMultipleTextNodes() throws Exception { + String query = "//person/first/text()"; + + ResourceSet resultSet = xpathservice.query(query); + assertEquals(2, resultSet.getSize()); + + assertEquals("John", resultSet.getResource(0).getContent()); + assertEquals("Sally", resultSet.getResource(1).getContent()); + } + + public void testFetchAttributeNode() throws Exception { + String document3 = "<?xml version=\"1.0\"?>" + "<foo bar='foo'>" + "<bar foo='bar' bar='bar'/>" + "</foo>"; + client.insertDocument(TEST_COLLECTION_PATH, "doc3", document3); + + try { + String query = "//foo/@bar"; + + ResourceSet resultSet = xpathservice.query(query); + assertEquals(1L, resultSet.getSize()); + + Node result = ((XMLResource) resultSet.getResource(0)).getContentAsDOM(); + assertEquals("foo", result.getChildNodes().item(0).getAttributes().item(0).getNodeValue()); + } finally { + client.removeDocument(TEST_COLLECTION_PATH, "doc3"); + } + } + + public void testFetchMultipleAttributeNode() throws Exception { + String document3 = "<?xml version=\"1.0\"?>" + "<foo bar='foo'>" + "<bar foo='bar' bar='bar'/>" + "</foo>"; + client.insertDocument(TEST_COLLECTION_PATH, "doc3", document3); + + try { + String query = "//@bar"; + + ResourceSet resultSet = xpathservice.query(query); + assertEquals(2, resultSet.getSize()); + + Node result0 = ((XMLResource) resultSet.getResource(0)).getContentAsDOM(); + Node result1 = ((XMLResource) resultSet.getResource(1)).getContentAsDOM(); + assertEquals("foo", result0.getChildNodes().item(0).getAttributes().item(0).getNodeValue()); + assertEquals("bar", result1.getChildNodes().item(0).getAttributes().item(0).getNodeValue()); + } finally { + client.removeDocument(TEST_COLLECTION_PATH, "doc3"); + } + } + + public void testFetchBoolean() throws Exception { + String query = "boolean(//person)"; + + ResourceSet resultSet = xpathservice.query(query); + assertEquals(2L, resultSet.getSize()); + + String result0 = (String)resultSet.getResource(0).getContent(); + String result1 = (String)resultSet.getResource(1).getContent(); + assertEquals("true", result0); + assertEquals("true", result1); + } + + public void testFetchString() throws Exception { + String query = "string(//person[first='John' and last='Smith']/first)"; + + try { + ResourceSet resultSet = xpathservice.query(query); + + assertEquals(2L, resultSet.getSize()); + } catch (XMLDBException e) { + fail(e.getMessage()); + } + } + + public void testFetchNumber() throws Exception { + String query = "count(//person[first='John' and last='Smith'])"; + + try { + ResourceSet resultSet = xpathservice.query(query); + + assertEquals(2L, resultSet.getSize()); + } catch (XMLDBException e) { + fail(e.getMessage()); + } + } + + public void testSrcAddedToRootOnly() throws Exception { + String query = "//person[first='John' and last='Smith']"; + + ResourceSet resultSet = xpathservice.query(query); + assertEquals(1, resultSet.getSize()); + + XMLResource resource = (XMLResource) resultSet.getResource(0); + + String john = + "<?xml version=\"1.0\"?>" + + "<person xmlns:src='http://xml.apache.org/xindice/Query' src:col='/db/testing/current' src:key='doc1'>" + + "<first>John</first>" + + "<last>Smith</last>" + + "<age>30</age>" + + "<phone type=\"work\">555-345-6789</phone>" + + "</person>"; + + // ensure that the resource has the correct doc id. + assertEquals("doc1", resource.getDocumentId()); + + XMLAssert.assertXMLEqual(john, TextWriter.toString(resource.getContentAsDOM())); + } + + public void testConflictingPrefix() throws Exception { + String document3 = + "<?xml version=\"1.0\"?>" + + "<src:person xmlns:src='http://example.net/person' >" + + "<src:first>Sally</src:first>" + + "<src:last>Smith</src:last>" + + "<src:phone type=\"work\">555-345-6789</src:phone>" + + "</src:person>"; + this.client.insertDocument(TEST_COLLECTION_PATH, "doc3", document3); + + String query = "//h:person[h:first='Sally' and h:last='Smith']/h:first"; + + xpathservice.setNamespace("h", "http://example.net/person"); + + ResourceSet resultSet = xpathservice.query(query); + assertEquals(1, resultSet.getSize()); + + XMLResource resource = (XMLResource) resultSet.getResource(0); + + // ensure that the resource has the correct doc id. + assertEquals("doc3", resource.getDocumentId()); + + Node node = resource.getContentAsDOM(); + + // add source node information to the compared xml as it's added by + // the query processor. + XMLAssert.assertXMLEqual("<first xmlns:src='http://xml.apache.org/xindice/Query' src:col='/db/testing/current' src:key='doc3' xmlns='http://example.net/person'>Sally</first>", + TextWriter.toString(node)); + + this.client.removeDocument(TEST_COLLECTION_PATH, "doc3"); + } + + public void testNamespacesNotImportedDeep() throws Exception { + // make sure that we don't have the namespace defs needlessly + // imported from the root all the way through the tree + // i.e. namespaces imported from above root should not + // be spread into child nodes + String document3 = + "<?xml version=\"1.0\"?>" + + "<p:person xmlns:p='http://example.net/person' >" + + "<p:first>Sally</p:first>" + + "<p:last>Smith</p:last>" + + "<p:phone p:type=\"work\">555-345-6789</p:phone>" + + "</p:person>"; + this.client.insertDocument(TEST_COLLECTION_PATH, "doc3", document3); + + String query = "//h:person[h:first='Sally' and h:last='Smith']"; + + xpathservice.setNamespace("h", "http://example.net/person"); + + ResourceSet resultSet = xpathservice.query(query); + assertEquals(1, resultSet.getSize()); + + XMLResource resource = (XMLResource) resultSet.getResource(0); + Node node = resource.getContentAsDOM(); + String retrieved = TextWriter.toString(node); + assertFalse("Namespace definitions imported deep in: " + retrieved, -1 == retrieved.indexOf("<p:first>")); + + // ensure that the resource has the correct doc id. + assertEquals("doc3", resource.getDocumentId()); + + // add source node information to the compared xml as it's added by + // the query processor. Note, this should work using without the + // prefixes in the control document using the default namespace, + // (i.e. xmlns='http://example.net/person') but I couldn't get it to work + // with XMLAssert (and we'return not testing XMLAssert so we just use the prefixes here too) + XMLAssert.assertXMLEqual("<p:person xmlns:p='http://example.net/person' xmlns:src='http://xml.apache.org/xindice/Query' src:col='/db/testing/current' src:key='doc3'>" + + "<p:first>Sally</p:first>" + + "<p:last>Smith</p:last>" + + "<p:phone p:type=\"work\">555-345-6789</p:phone>" + + "</p:person>", + TextWriter.toString(node)); + + this.client.removeDocument(TEST_COLLECTION_PATH, "doc3"); + } + + public void testMathOpQuery() throws Exception { + // force a non-XObject Object to be supplied to evalMathOperation as + // one of its operands + // this works in the buggy version of XPathQueryResolver but only + // because a ClassCastException that cuts short the indexing evaluation + // is caught and ignored forcing a collection scan (if logging WARN, you'll see stack trace) + + String query = "//person[substring(last, string-length(last) - two)='ith']"; + String document3 = + "<?xml version=\"1.0\"?>" + + "<person>" + + "<first>Sally</first>" + + "<last>Smith</last>" + + "<one>1</one>" + + "<two>2.0</two>" + + "<phone call=\"no\" type=\"work\">555-345-6789</phone>" + + "</person>"; + this.client.insertDocument(TEST_COLLECTION_PATH, "doc3", document3); + + try { + ResourceSet resultSet = xpathservice.query(query); + assertEquals(1, resultSet.getSize()); + } finally { + this.client.removeDocument(TEST_COLLECTION_PATH, "doc3"); + } + } } 1.2 +12 -3 xml-xindice/java/src/org/apache/xindice/core/query/QueryUtil.java Index: QueryUtil.java =================================================================== RCS file: /home/cvs/xml-xindice/java/src/org/apache/xindice/core/query/QueryUtil.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- QueryUtil.java 24 Feb 2004 03:20:27 -0000 1.1 +++ QueryUtil.java 24 Feb 2004 15:44:01 -0000 1.2 @@ -25,6 +25,7 @@ import org.apache.xindice.xml.dom.DBNode; import org.apache.xindice.xml.dom.DocumentImpl; +import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -63,7 +64,15 @@ int count = 0; while (nodeSet != null && nodeSet.hasMoreNodes()) { final Object element = nodeSet.getNextNode(); - if (element instanceof Node) { + if (element instanceof Attr) { + Attr n = (Attr) element; + + // FIXME: This should be namespaced element in XindiceCollection.QUERY_NS namespace + Element holder = doc.createElement("result"); + holder.setAttributeNode((Attr)doc.importNode(n, true)); + + root.appendChild(holder); + } else if (element instanceof Node) { Node n = (Node) element; if (n.getNodeType() == Node.DOCUMENT_NODE) { 1.37 +4 -0 xml-xindice/status.xml Index: status.xml =================================================================== RCS file: /home/cvs/xml-xindice/status.xml,v retrieving revision 1.36 retrieving revision 1.37 diff -u -r1.36 -r1.37 --- status.xml 24 Feb 2004 15:32:27 -0000 1.36 +++ status.xml 24 Feb 2004 15:44:01 -0000 1.37 @@ -69,6 +69,10 @@ <changes> <release version="1.1b4-dev" date="February 24 2004"> + <action dev="VG" type="fix" fixes-bug="22156"> + XPath query resulting in attribute nodes will return attributes + on the <result> element. + </action> <action dev="VG" type="fix"> Fixed bug with DocumentImpl.importNode when importing attribute nodes. </action>