views:

53

answers:

2

In my code below, I am trying to access my 'handler' XML elements using XPath, but I am having no luck - the 'elemHandler' element is always null. Can anyone share with me the obvious solution? Thanks in advance.

import java.io.IOException;
import java.io.StringReader;

import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;

public class XPathTest {
    private static String jobString = "<job name=\"Workflow.JOB\">" + 
                                           "  <handler name=\"xslt.converter\"/>" +
                                           "  <handler name=\"openoffice.renderer\">" +
                                           "    <opts input=\"ODS\" output=\"PDF\"/>" +
                                           "  </handler>" +
                                           "</job>";

    public static void main(String[] args) {
    try {
        Element elemJobInfo = new SAXBuilder().build(new StringReader(jobString)).detachRootElement();
        XPath handlerExpression = XPath.newInstance("//stp:handler[2]");
        handlerExpression.addNamespace("stp", "http://service.mine.org/dgs");
        Element elemHandler = (Element) handlerExpression.selectSingleNode(elemJobInfo);
        jobString = elemHandler.toString();
    }
    catch (IOException e) {
        System.out.println("Failure: " + e);
    }
    catch (JDOMException e) {
        System.out.println("Failure: " + e);
    }
    catch (Exception e) {
        System.out.println("Failure: " + e);
    }
}
}
+1  A: 

What's up with the stp namespace? The XML in jobString doesn't reference any namespaces. Have you tried it without the prefix?

//handler[2]
John Kugelman
Yes, I have. Research shows that XPath does not work with unqualified and/or the default namespace. You must provide one.
XPath does indeed work with the default namespace. The only namespace issue it has that I'm aware of is that it doesn't respect `xmlns="some-uri"` declarations. If you change the empty prefix in your document XPath will ignore it; it requires a namespace prefix for elements not in the default namespace. For example, you can't use `/html` to match `<html xmlns="http://www.w3.org/...">` in an XHTML document.
John Kugelman
+1  A: 

The XML document against which the XPath expression:

//stp:handler[2]

is evaluated, has no default or declared namespaces and all nodes are in "no namespace". There isn't any node in the "http://service.mine.org/dgs" namespace. Unless you are using another XML document in your actual case, the above expression must not select any node -- and this is exactly what you get.

In case you are using a document that you haven't shown, that really has a default namespace, the chances are you have misspelt the namespace in your Java code.

Also, do try this variation of your XPath expression (with or without the namespace prefix):

(//stp:handler)[2]

Dimitre Novatchev
Thanks Dimitre. I did try that variation and it did not work. At this point, I have tried many variations including fully name-spacing the XML document, etc.In whatever forums that I have posted this so far, everyone except you seems more interested in intelectual combat than getting to something that works. I do long for someone to take the code snippet, grab jdom.jar and jaxen.jar and tell me how this should really work.
@topsquire: Unfortunately I don't work with Java. Had it been C# or MSXML DOM, I would be able to help. This seems not to be an XPath question, because in any other environment the non-namespaced expressions would select node(s). Most probably you aren't using the Java XPath API as necessary. Please, consult the avilable documentation -- usually it contains examples that you may follow. Also, you may ask in a Java-related forum.I *can* prove to you what nodes are selected by particular XPath expressions -- by evaluating them in an environment where XSLT is the language that hosts XPath.
Dimitre Novatchev