具有属性的元素的正确XPath表达式是什么?

时间:2015-12-17 17:16:26

标签: xml xpath

我有XML文档,片段在

下面
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>myapp.applications</groupId>
        <artifactId>myartifact</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

我想选择与{/ 1>类似的groupId的值

xml.xpath("//project/parent/groupId").text

这不是所有属性的结果。我想。

如果将文档更改为

<?xml version="1.0" encoding="UTF-8"?>
<project>
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>myapp.applications</groupId>
        <artifactId>myartifact</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

它确实有用。

因此,似乎XPath表达式对于具有属性的项目元素无效。

什么是正确的XPath表达式?

2 个答案:

答案 0 :(得分:2)

问题是xmlns“属性”不属于属性,它们是命名空间定义。元素//project表示“在空名称空间中项目”,但您的project位于非空名称空间中。您需要使用前缀注册名称空间(语法取决于您使用的语言),然后使用

//p:project/p:parent/p:groupId

答案 1 :(得分:1)

1你可以在root用户使用:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

2也这样做

builderFactory.setNamespaceAware(true);
DocumentBuilder builder = builderFactory.newDocumentBuilder();

3然后

String expression="//project/parent/groupId";

XPath xpath = XPathFactory.newInstance().newXPath();
NamespaceContext ctx = new NamespaceContext() {
    public String getNamespaceURI(String prefix) {
        if (prefix == null) throw new NullPointerException("Null prefix");
        return XMLConstants.NULL_NS_URI;
    }
    public String getPrefix(String uri) {
        throw new UnsupportedOperationException();
    }
    public Iterator getPrefixes(String uri) {
        throw new UnsupportedOperationException();
    }
};
xpath.setNamespaceContext(ctx);
XPathExpression expr = xpath.compile(expression) ; 

NodeList nodes  = (NodeList) expr.evaluate(document, XPathConstants.NODESET);

它有效