  | |  | Weird behavior of XPath.evaluate() | Weird behavior of XPath.evaluate() 2007-05-10 - By Christine Li
Hi, Jason
Set namespace aware to true on DocumentBuilderFactory.
DocumentBuilderFactory fct = DocumentBuilderFactory.newInstance (); fct.setNamespaceAware(true);
Christine Li XSLT Development IBM Toronto Lab Tel: (905)413-2601 Email: jycli@(protected)
"Jason Morris" <jason.morris@(protected)> Sent by: jm56692@(protected) 10/05/2007 12:19 PM
To xalan-j-users@(protected) cc
Subject Weird behavior of XPath.evaluate()
Hi all,
Apologies if this has been asked before but it is driving me mad. I am happily able to evaluate non-namespaced XPath expressions using either an InputSource or a document context element. I can evaluate namespaced expressions using the InputSource, but it doesn't work if I evaluate a namespaced expression passing an Element as a context node.
Take the example file from http://xml.apache.org/xalan-j/xpath_apis.html#namespacecontext
<?xml version='1.0'?>
<foo:document xmlns:foo="http://apache.org/foo" xmlns:bar=" http://apache.org/bar"> <bar:element>MyBar</bar:element> </foo:document> I want to evaluate "/foo:document/bar:element", which should return "MyBar". I use the following code:
package test;
import java.util.Iterator;
import javax.xml.XMLConstants; import javax.xml.namespace.NamespaceContext; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathFactory ;
import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.InputSource;
public class NamespaceTest { public static void main(String[] argv) throws Exception { String doc = " namespace.xml"; String xPath = "/foo:document/bar:element";
// Parse the doc independently to get the root Element DocumentBuilderFactory fct = DocumentBuilderFactory.newInstance (); DocumentBuilder builder = fct.newDocumentBuilder(); Document document = builder.parse("file:" + doc); Element rootElement = document.getDocumentElement();
// Setup the namespace context XPathFactory factory = XPathFactory.newInstance(); XPath xp = factory.newXPath(); NamespaceContext ctx = new MyNamespaceContext(); xp.setNamespaceContext(ctx); // Create an InputSource of the file InputSource is = new InputSource(doc); // This works String resultString1 = xp.evaluate(xPath,is); // This doesn't String resultString2 = xp.evaluate (xPath,rootElement);
System.out.println("RES1=" + resultString1); System.out.println("RES2=" + resultString2); } }
class MyNamespaceContext implements NamespaceContext { public String getNamespaceURI(String prefix) { if (prefix.equals("foo")) return " http://apache.org/foo"; else if ( prefix.equals("bar")) return "http://apache.org/bar"; else return XMLConstants.NULL_NS_URI; } public String getPrefix(String namespace) { if (namespace.equals("http://apache.org/foo")) return "foo"; else if (namespace.equals(" http://apache.org/bar")) return "bar"; else return null; }
public Iterator getPrefixes(String namespace) { return null; } }
When I execute this (against Xalan 2.7.0), resultString1 returns "MyBar" correctly, resultString2 is set as empty string. Surely they should both return the correct result? Interestingly, if I use the exact same code to evaluate a namespace-free expression, both versions work fine.
Is this a bug, or am I doing something stupid with the rootElement I am passing in?
Any and all assistance greatly appreciated,
Jason
<br><font size=2 face="sans-serif">Hi, Jason</font> <br> <br><font size=2 face="sans-serif">Set namespace aware to true on DocumentBuilderFactory.</font> <br> <br><font size=3>DocumentBuilderFactory fct = DocumentBuilderFactory.newInstance ();</font> <br><font size=2 face="sans-serif">fct.setNamespaceAware(true);</font> <br> <br><font size=2 face="sans-serif">Christine Li<br> XSLT Development<br> IBM Toronto Lab<br> Tel: (905)413-2601<br> Email: jycli@(protected)</font> <br> <br> <br> <table width=100%> <tr valign=top> <td width=40%><font size=1 face="sans-serif"><b>"Jason Morris" <jason.morris@(protected)></b> </font> <br><font size=1 face="sans-serif">Sent by: jm56692@(protected)</font> <p><font size=1 face="sans-serif">10/05/2007 12:19 PM</font> <td width=59%> <table width=100%> <tr valign=top> <td> <div align=right><font size=1 face="sans-serif">To</font></div> <td><font size=1 face="sans-serif">xalan-j-users@(protected)</font> <tr valign=top> <td> <div align=right><font size=1 face="sans-serif">cc</font></div> <td> <tr valign=top> <td> <div align=right><font size=1 face="sans-serif">Subject</font></div> <td><font size=1 face="sans-serif">Weird behavior of XPath.evaluate()</font>< /table> <br> <table> <tr valign=top> <td> <td></table> <br></table> <br> <br> <br><font size=3>Hi all,<br> <br> Apologies if this has been asked before but it is driving me mad. I am happily able to evaluate non-namespaced XPath expressions using either an InputSource or a document context element. I can evaluate namespaced expressions using the InputSource, but it doesn't work if I evaluate a namespaced expression passing an Element as a context node. <br> <br> Take the example file from </font><a href="http://xml.apache.org/xalan-j/xpath _apis.html#namespacecontext" target=_blank><font size=3 color=blue><u>http://xml .apache.org/xalan-j/xpath_apis.html#namespacecontext </u></font></a><font size=3><br> <br> <?xml version='1.0'?><br> <br> <foo:document xmlns:foo="</font><a href=http://apache.org/foo target= _blank><font size=3 color=blue><u>http://apache.org/foo</u></font></a><font size =3>" xmlns:bar="</font><a href=http://apache.org/bar target=_blank><font size=3 color=blue><u> http://apache.org/bar</u></font></a><font size=3>"><br> <bar:element>MyBar</bar:element> <br> </foo:document><br> <br> I want to evaluate "/foo:document/bar:element", which should return "MyBar". I use the following code:<br> <br> package test;<br> <br> import java.util.Iterator;<br> <br> import javax.xml.XMLConstants;<br> import javax.xml.namespace.NamespaceContext;<br> import javax.xml.parsers.DocumentBuilder;<br> import javax.xml.parsers.DocumentBuilderFactory;<br> import javax.xml.xpath.XPath;<br> import javax.xml.xpath.XPathFactory ;<br> <br> import org.w3c.dom.Document;<br> import org.w3c.dom.Element;<br> import org.xml.sax.InputSource;<br> <br> public class NamespaceTest<br> {<br> public static void main(String[] argv) throws Exception<br> {<br> String doc = " namespace.xml";<br> String xPath = "/foo:document/bar:element" ;;<br> <br> // Parse the doc independently to get the root Element<br> DocumentBuilderFactory fct = DocumentBuilderFactory .newInstance ();<br> DocumentBuilder builder = fct.newDocumentBuilder(); <br> Document document = builder.parse("file:" + doc);<br> Element rootElement = document.getDocumentElement() ;<br> <br> // Setup the namespace context <br> XPathFactory factory = XPathFactory.newInstance(); <br> XPath xp = factory.newXPath();<br> NamespaceContext ctx = new MyNamespaceContext();<br> xp.setNamespaceContext(ctx);<br> <br> // Create an InputSource of the file <br> InputSource is = new InputSource(doc);<br> <br> // This works<br> String resultString1 = xp.evaluate(xPath,is);<br> // This doesn't<br> String resultString2 = xp.evaluate (xPath ,rootElement);<br> <br> System.out.println("RES1=" + resultString1);<br> System.out.println("RES2=" + resultString2);<br> }<br> }<br> <br> <br> <br> class MyNamespaceContext implements NamespaceContext <br> {<br> public String getNamespaceURI(String prefix)<br> {<br> if (prefix.equals("foo"))<br> return "</font><a href=http:/ /apache.org/foo target=_blank><font size=3 color=blue><u> http://apache.org/foo</u></font></a><font size=3>";<br> else if ( prefix.equals("bar"))<br> return "</font><a href=http:/ /apache.org/bar target=_blank><font size=3 color=blue><u>http://apache.org/bar< /u></font></a><font size=3>";<br> else<br> return XMLConstants.NULL_NS_URI;<br> }<br> <br> public String getPrefix(String namespace) <br> {<br> if (namespace.equals("</font><a href=http:/ /apache.org/foo target=_blank><font size=3 color=blue><u>http://apache.org/foo< /u></font></a><font size=3>"))<br> return "foo"; <br> else if (namespace.equals("</font><a href=http ://apache.org/bar target=_blank><font size=3 color=blue><u> http://apache.org/bar</u></font></a><font size=3>"))<br> return "bar";<br> else<br> return null;<br> }<br> <br> public Iterator getPrefixes(String namespace)<br> {<br> return null;<br> } <br> } <br> <br> <br> When I execute this (against Xalan 2.7.0), resultString1 returns "MyBar " correctly, resultString2 is set as empty string. Surely they should both return the correct result? Interestingly, if I use the exact same code to evaluate a namespace-free expression, both versions work fine. <br> <br> Is this a bug, or am I doing something stupid with the rootElement I am passing in?<br> <br> Any and all assistance greatly appreciated,<br> <br> Jason<br> </font> <br>
|
|
 |