An SO User
An SO User

Reputation: 24998

My XPath expression does not select anything in Java

I was evaluating an XPath expression in Java and it was supposed to return just a single String value in return.
However, all I get is a blank value.

SSCCE

import javax.xml.xpath.*;
import java.io.*;
import org.xml.sax.*;

public class XPathBasic{
    public static void main(String[] args){
        XPathFactory factory;
        XPath xPath;
        XPathExpression xPathExpressionCompiled;
        String xPathExpressionString;
        File xmlFile;
        InputSource inputSource;

        try{
            factory = XPathFactory.newInstance();
            xPath = factory.newXPath();
            xPathExpressionString = "/people/student[@scholarship='yes']/name";
            xPathExpressionCompiled = xPath.compile(xPathExpressionString);

            xmlFile = new File("helloWorld.xml");
            inputSource = new InputSource(new FileInputStream(xmlFile));
            String name = xPathExpressionCompiled.evaluate(inputSource);

            if(name != null){
                System.out.println("Name of the student is: " + name);
            }else{
                System.out.println("Error");
            }
        }catch(XPathExpressionException e){
            System.out.println("There seems to be an error with your expression: " + e.getMessage());
        }catch(IOException e){

        }catch(Exception e){

        }

    }
}  

XML

<?xml version="1.0" encoding="UTF-8" ?>
<people xmlns="http://www.cmu.edu/ns/blank" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.cmu.edu/ns/blank student.xsd">
    <student scholarship="yes">
        <name>John</name>
        <course>Computer Technology</course>
        <semester>6</semester>
        <scheme>E</scheme>
    </student>

    <student scholarship="no">
        <name>Foo</name>
        <course>Industrial Electronics</course>
        <semester>6</semester>
        <scheme>E</scheme>
    </student>
</people>  

Output

Name of student is:

I was expecting to see John there. Can someone please tell me what went wrong ?

Upvotes: 2

Views: 276

Answers (2)

ABC123
ABC123

Reputation: 1065

I used Jaxen with Jdom2 and found this helpful: http://www.edankert.com/defaultnamespaces.html

One way to make it work is to define a prefix for your default namespace. Here I named it default. (You can name the prefix anything you want.) Then reference the new prefix in your xpath.

Namespace nameSpaceDefault = 
    Namespace.getNamespace("default", "http://www.cmu.edu/ns/blank");
Namespace nameSpaceXsi = 
    Namespace.getNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");

nameSpaces.add(nameSpaceDefault);
nameSpaces.add(nameSpaceXsi);

String xpath = "/default:people/default:student[@scholarship='yes']/default:name/text()";

XPathExpression<Text> xpathExpression = XPathFactory.instance().
            compile(xpath, Filters.text(), null, nameSpaces);

//Jdom2 document
Document document = ...;  

//Evaluate xpath
List<Text> textValues = xpath.evaluate(document);  

Upvotes: 1

peter.murray.rust
peter.murray.rust

Reputation: 38043

This is a mistake that many of us make! Xpath is sensitive to namespaces. Your XML file contains namespaced elements and these namespaces are required in the XPath. In the XML file you can use a default namespace, but not in XPath.

try

"/people[namespace-uri()='http://www.cmu.edu/ns/blank']/student[namespace-uri()='http://www.cmu.edu/ns/blank' and @scholarship='yes']/name[namespace-uri()='http://www.cmu.edu/ns/blank']"

and it should work.

Your system probably allows namespaces prefixes in the XPath. These cannot be empty. An example might be:

"/a:people/a:student[@scholarship='yes']/a:name"

How you map the namespace prefix (a) depends on the software. Note any prefix will do as long as it is mapped.

Upvotes: 2

Related Questions