2

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 ?

4

2 回答 2

2

这是我们很多人都会犯的错误!Xpath 对命名空间很敏感。您的 XML 文件包含命名空间元素,这些命名空间在 XPath 中是必需的。在 XML 文件中,您可以使用默认名称空间,但不能在 XPath 中使用。

尝试

"/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']"

它应该可以工作。

您的系统可能允许在 XPath 中使用名称空间前缀。这些不能为空。一个例子可能是:

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

如何映射命名空间前缀 (a) 取决于软件。请注意,只要它被映射,任何前缀都可以。

于 2013-05-13T20:39:22.887 回答
1

我将 Jaxen 与 Jdom2 一起使用,发现这很有帮助: http ://www.edankert.com/defaultnamespaces.html

使其工作的一种方法是为您的默认命名空间定义一个前缀。这里我将其命名为默认值。(您可以随意命名前缀。)然后在 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);  
于 2014-06-20T15:23:59.780 回答