Namespace prefix support
Added by Anonymous over 19 years ago
Legacy ID: #3301745 Legacy Poster: dstartup (dstartup)
After trying to suss out a problem for a while, I finally decided to read the XPath2.0 spec aboout namespace prefix support in XPath querying. I initially thought that using namespace prefixes had ceased working in the later versions of saxon. However, I have now discovered that the use of namespace prefixes has been deprecated in XPath 2.0 to be replaced by the use of functions. I was hoping that someone might provide some advice on the following issues. 1. Does Saxon 8 provide backwards compatability for the use of prefixes in Xpath queries (I imagine not, I just want to confirm this). 2. I've encountered a potential problem with running XPath queries when a default namespace is defined and I want to know if what I am trying to do is an invalid XPath 2.0 query. I've created a simple xml file and example xpath to highlight the problem. <?xml version="1.0"?> <bob xmlns="www.example.com"> <frank earnie="2"> gnome </frank> <frank earnie="3"> freddy </frank> </bob> This xml document has a default namespace so I'd expect to be able to successfully evaluate the following XPath against it: 'bob/frank/text()' to get a result of 'gnome'. However, this xpath query returns an empty list. If I then modify the XPath to use the local-name() function so that it looks like this [local-name()='bob']/[local-name()='frank']/text() it returns the expected value of 'gnome'.
Replies (4)
Please register to reply
RE: Namespace prefix support - Added by Anonymous over 19 years ago
Legacy ID: #3301797 Legacy Poster: Michael Kay (mhkay)
You seem to be confused. When it comes to namespaces, this is a rather common state of affairs! "However, I have now discovered that the use of namespace prefixes has been deprecated in XPath 2.0 to be replaced by the use of functions." The only thing that has been deprecated is the use of the namespace axis, which seems unrelated to your problem. Saxon continues to support the namespace axis, and I have no intention of dropping it. In XPath 1.0, if your elements were in a namespace (albeit the default namespace), then to refer to them in an XPath expression you always needed to prefix them. So in your example you need to write x:bob/x:frank/text() after binding the namespace prefix x to www.example.com XPath 2.0 now recognizes something called the "default element namespace". If a default element namespace is defined in the static context, then the above expression can be written bob/frank/text() You can define a default element namespace in XSLT using the default-xpath-namespace attribute on any XSLT instruction in the stylesheet. In XQuery, you can define a default element namespace simply by declaring a default namespace in the query prolog or on any direct element constructor. In the JAXP API for free-standing evaluation of XPath expressions, there is currently no way to establish a default element namespace, so the old (XPath 1.0) rules continue to apply: that is, the element names in the path expression must be prefixed. It's not clear from your post how you are executing the XPath expression, but I hope this clarifies the situation. Michael Kay
RE: Namespace prefix support - Added by Anonymous over 19 years ago
Legacy ID: #3301994 Legacy Poster: dstartup (dstartup)
Thanks for the response. You've cleared up a few issues in my mind about what is going on between XPath 1 and 2. Sorry, I forgot to add on a last few comments about the context I was working in. I'm using Saxon for doing individual XPath evaluation queries from my application over a given xml document. So I'm using the free-standing XPath expression evaluator with JAXP 1.3 using the XPathExpressionImpl. I've still been getting problems with evaluating XPaths that contain prefixed expressions eg m:bob/m:frank/text() which returns the error 'Prefix m has not been declared'. I think that the problem I'm having is that I've not setup a namespace resolver so that the prefixes aren't being handled properly. Unfortuantly the code has to be able to take any xml document and so I can't initially hard code any namespace prefixes. I'll have to write a NamespaceResolver that can resolve the prefixes of any given xml document. Shouldn't be to difficult to do, although I was wondering if any such NamespaceResolver already exists.
RE: Namespace prefix support - Added by Anonymous over 19 years ago
Legacy ID: #3302268 Legacy Poster: Michael Kay (mhkay)
The JAXP interface here is called NamespaceContext; there's an interface with a similar purpose in Saxon called NamespaceResolver. If you have a NamespaceResolver, you can turn it into a NamespaceContext by doing new NamespaceContextImpl(nsResolver) If you want to use all the namespace declarations that are in scope for a particular node in a source document, there is an InscopeNamespaceResolver that does this for you. So given a NodeInfo n, you can do new NamespaceContextImpl(new InscopeNamespaceResolver(n)) Michael Kay
RE: Namespace prefix support - Added by Anonymous about 19 years ago
Legacy ID: #3351040 Legacy Poster: Anurag Chakravarti (anurag2002)
Hi, I always get a null exception while using XPATH evaluator Saxon-8.5.1b. I am using this for the first time. My xml document is: <foo xmlns="default-namespace"> <ns1:bar xmlns:ns1="namespace1-uri" xmlns="namespace1-uri"> <baz/> <ns2:baz xmlns:ns2="namespace2-uri"/> </ns1:bar> <ns3:hi xmlns:hi="namespace3-uri"> <there/> </ns3:hi> </foo> XPATH expression is /foo/a:bar/b:baz java code is: String xpathExpr = "/foo/a:bar/b:baz"; try { XPathFactory xpf = XPathFactory.newInstance(NamespaceConstant.OBJECT_MODEL_SAXON); } catch( javax.xml.xpath.XPathFactoryConfigurationException exception ) { System.out.println( "Exception XPathFactory.newInstance" ); } StandaloneContext context = new StandaloneContext(); context.declareNamespace("a","namespace1-uri"); context.declareNamespace("b","namespace1-uri"); NamespaceContext namespaceContext = new NamespaceContextImpl(context); InputSource is = new InputSource(xmlExpr); SAXSource ss = new SAXSource(is); XPathEvaluator xpe = new XPathEvaluator(); xpe.setNamespaceContext(namespaceContext); String result = null; try { result = xpe.evaluate(xpathExpr, ss); } catch( javax.xml.xpath.XPathExpressionException exception ) { System.out.println( exception.getCause() ); } I always get a exception and exception.getCause gives me null. Any suggestions would be of great help. As you can see I am new to all this :-) Thanks -Anurag
Please register to reply