You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-user@db.apache.org by Douglas Russell <do...@comlab.ox.ac.uk> on 2007/06/21 11:58:49 UTC

Derby XMLQUERY XPATH

I've got some XML with namespaces and I just can't find a way to set the 
namespace in my query.

If I do (Using a standard Connection in java):

statement.execute(
		"SELECT ID, " +
			"XMLSERIALIZE( " +
				"XMLQUERY('/' PASSING BY REF Definition EMPTY ON EMPTY) " +
			"AS VARCHAR(10000)) " +
			"FROM My_Schema.My_Table");

Where my XML looks like:
<tns:MyProject xmlns:tns="http://www.myproject.ox.ac.uk/MyProject" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://www.myproject.ox.ac.uk/MyProject MyProject.xsd">
    <tns:Name>Douglas</tns:Name>
</tns:MyProject>

and my database is just 2 columns: ID (Varchar) and Definition (XML).

The XPATH '/' gets all the XML in Definition, that works. If I try and search 
for '//Name' however, I get nothing. Presumably this is because Name is 
actually in a namespace. How do I construct my XPATH to look for this?

I've tried:
'//myns:Name' and that would seem to be correct, but I can find no way of 
setting myns to resolve to "http://www.myproject.ox.ac.uk/MyProject" in 
Derby. When I do that I just get the error:

Caused by: org.apache.derby.client.am.SqlException: Encountered error while 
evaluating XML query expression for XMLQUERY operator: Prefix must resolve to 
a namespace: myns SQLSTATE: XJ001: Java exception: 'Prefix must resolve to a 
namespace: myns: org.apache.xpath.domapi.XPathStylesheetDOM3Exception'.

Any help would be much appreciated.

Cheers

-- 
Douglas PW Russell
Research Officer - GIMI/NeuroGrid
Oxford University Computing Laboratory
Tel:	+44 (0)1865 283519
email:	douglas.russell@comlab.ox.ac.uk

Re: Derby XMLQUERY XPATH

Posted by Douglas Russell <do...@comlab.ox.ac.uk>.
I tried:

statement.execute(
                "SELECT ID, " +
                        "XMLSERIALIZE( " +
                                "XMLQUERY(' 
xmlns:myns=\"http://www.myproject.ox.ac.uk/MyProject\" //myns:Name' PASSING 
BY REF Definition EMPTY ON EMPTY) " +
                        "AS VARCHAR(10000)) " +
                        "FROM My_Schema.My_Table");

Same error:
Caused by: org.apache.derby.client.am.SqlException: Encountered error while 
evaluating XML query expression for XMLQUERY operator: Prefix must resolve to 
a namespace: myns SQLSTATE: XJ001: Java exception: 'Prefix must resolve to a 
namespace: myns: org.apache.xpath.domapi.XPathStylesheetDOM3Exception'.

Cheers

On Thursday 21 Jun 2007, Bryan Pendleton wrote:
> > I've tried:
> > '//myns:Name' and that would seem to be correct, but I can find no way of
> > setting myns to resolve to "http://www.myproject.ox.ac.uk/MyProject" in
>
> Did you try including
>
>    xmlns:myns="http://www.myproject.ox.ac.uk/MyProject"
>
> in your XQuery expression?
>
> I don't know if it will work, but it's worth a try.
>
> thanks,
>
> bryan



-- 
Douglas PW Russell
Research Officer - GIMI/NeuroGrid
Oxford University Computing Laboratory
Tel:	+44 (0)1865 283519
email:	douglas.russell@comlab.ox.ac.uk

Re: Derby XMLQUERY XPATH

Posted by Bryan Pendleton <bp...@amberpoint.com>.
> I've tried:
> '//myns:Name' and that would seem to be correct, but I can find no way of 
> setting myns to resolve to "http://www.myproject.ox.ac.uk/MyProject" in 

Did you try including

   xmlns:myns="http://www.myproject.ox.ac.uk/MyProject"

in your XQuery expression?

I don't know if it will work, but it's worth a try.

thanks,

bryan


Re: Derby XMLQUERY XPATH

Posted by Douglas Russell <do...@comlab.ox.ac.uk>.
Yeah, thanks, this is basically what I'd come up with as well, I was hoping 
there was a more elegant way though. In DB2 it looks like there is a way of 
setting the dictionary of namespaces to resolve in the database query which 
then gets passed though to the backend to use when resolving in Xalan. 
Presumably that's a feature that Derby will get in the future, allowing the 
myns:Name syntax to be used.

For reference, what I ended up with was (To get the text content of the Name 
field):

statement.execute(
		"SELECT ID, " +
			"XMLSERIALIZE( " +
				"XMLQUERY('//*[local-name()=\"Name\" and 
namespace-uri()=\"http://www.myproject.ox.ac.uk/MyProject\"]/text()' PASSING 
BY REF Definition EMPTY ON EMPTY) " +
			"AS VARCHAR(10000)) " +
			"FROM My_Schema.My_Table");

Thanks very much for your suggestions.

Douglas

-- 
Douglas PW Russell
Research Officer - GIMI/NeuroGrid
Oxford University Computing Laboratory
Tel:	+44 (0)1865 283519
email:	douglas.russell@comlab.ox.ac.uk

Re: Derby XMLQUERY XPATH

Posted by Army <qo...@gmail.com>.
Douglas Russell wrote:

> I've got some XML with namespaces and I just can't find a way to set the 
> namespace in my query.

<snip>

> The XPATH '/' gets all the XML in Definition, that works. If I try and search 
> for '//Name' however, I get nothing. Presumably this is because Name is 
> actually in a namespace. How do I construct my XPATH to look for this?

I think that in order to get this to work you have to query for "Name" as the 
*local* name, i.e. search for elements named "Name" in any namespace.  One way 
to do this is with an XPath expression like:

   //child::*[local-name()="Name"]

which should (I think?) return all Name elements. If you want to restrict the 
Name elements to a specific namespace, then you could do something like:

   //child::*[local-name()="Name" and
      namespace::*[string()="http://www.myproject.ox.ac.uk/MyProject"]]

I realize this is pretty (very) ugly, but I can't think of any better way at the 
moment.  It is of course very possible that there *is* a better way and I just 
don't know about it...

> I've tried:
> '//myns:Name' and that would seem to be correct, but I can find no way of 
> setting myns to resolve to "http://www.myproject.ox.ac.uk/MyProject" in 
> Derby. When I do that I just get the error:
> 
> Caused by: org.apache.derby.client.am.SqlException: Encountered error while 
> evaluating XML query expression for XMLQUERY operator: Prefix must resolve to 
> a namespace: myns SQLSTATE: XJ001: Java exception: 'Prefix must resolve to a 
> namespace: myns: org.apache.xpath.domapi.XPathStylesheetDOM3Exception'.

This error comes from the underlying Xalan engine, so perhaps you can find a way 
around this by searching Xalan documentation and/or help files?  If it is 
possible to set namespaces within an XPath query in Xalan, then hopefully it is 
documented somewhere.  And if it is, then feeding that into Derby as part of the 
query should (hopefully) return the desired results, since Derby ultimately just 
passes the query on to Xalan for evaluation...

Army