Perfect - works like a charm. Thanks so much Christine and Keshlam for a
simple fix to a stupid mistake!

Jason

On 5/10/07, Christine Li <[EMAIL PROTECTED]> wrote:


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: [EMAIL PROTECTED]


 *"Jason Morris" <[EMAIL PROTECTED]>*
Sent by: [EMAIL PROTECTED]

10/05/2007 12:19 PM
  To
xalan-j-users@xml.apache.org  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
* <http://xml.apache.org/xalan-j/xpath_apis.html#namespacecontext>

<?xml version='1.0'?>

<foo:document xmlns:foo="*http://apache.org/foo* <http://apache.org/foo>"
xmlns:bar="* http://apache.org/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* <http://apache.org/foo>";
       else if ( prefix.equals("bar"))
           return "*http://apache.org/bar* <http://apache.org/bar>";
       else
           return XMLConstants.NULL_NS_URI;
   }

   public String getPrefix(String namespace)
   {
       if (namespace.equals("*http://apache.org/foo*<http://apache.org/foo>
"))
           return "foo";
       else if (namespace.equals("* 
http://apache.org/bar*<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


Reply via email to