【问题标题】:Xpath retrieve the attribute of the node in javaXpath在java中检索节点的属性
【发布时间】:2021-07-13 16:17:52
【问题描述】:

我想检索一个带有属性的字段,但这不起作用。

这是我的 xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<fields>
    <field name="a" class="b" libelle="zozo"></field>
    <field name="c" class="c" libelle="zaza"></field>
</fields>

Xpath 表达式:

//field[@name[.='a'] and @class[.='b']]

Java 代码:

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.*;
import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String args[]) throws Exception {
        String fileName = Main.class.getResource("exemple.xml").getFile();
        Document document = getDocument(fileName);
        System.out.println(evaluateXPath(document, "//field[@name='a' and @class='b']")); //updated with the proposition of @Michael 
        System.out.println(evaluateXPath(document, "//field/@name[.='a']")); //to show you that the parser work a bit
    }


    private static Document getDocument(String fileName) throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(fileName);
        return doc;
    }

    private static List<String> evaluateXPath(Document document, String xpathExpression){

        XPathFactory xpathFactory = XPathFactory.newInstance();
        XPath xpath = xpathFactory.newXPath();
        List<String> values = new ArrayList<>();
        try {
            XPathExpression expr = xpath.compile(xpathExpression);
            NodeList nodes = (NodeList) expr.evaluate(document, XPathConstants.NODESET);
            if (nodes != null)
                for (int i = 0; i < nodes.getLength(); i++) {
                    if (nodes.item(i).getNodeValue() != null)
                        values.add(nodes.item(i).getNodeValue());
                }
        } catch (XPathExpressionException e) {
            e.printStackTrace();
        }
        return values;
    }
}

通过这个设置,我希望得到

<field name="a" class="b" libelle="zozo">

但我什么也没得到。 我尝试使用在线 Xpath 验证器,它可以工作,但在 Java 中却不行。

我看到它可能来自 xml 中的命名空间,但我的没有。

感谢您的帮助

解决方案

正如@Alexandra 下面所说,我使用的方法在我的情况下会返回 null。

为了从你必须使用的属性中检索值:

nodes.item(0).getAttributes().getNamedItem("YourAttributeName");

【问题讨论】:

  • 您的代码看起来不错(虽然有点复杂:您可以将谓词写成[@name='a' and @class='b'])。要么是您没有向我们展示的代码有问题,要么您发现了一个错误:顺便说一下,第一个选项似乎更有可能。
  • @Michael 我试过了,没有任何改变
  • 请尝试发布一个完整的独立Java程序来演示效果,看看其他人是否可以复制。
  • 感谢您的回复@Michael,我已更新帖子以包含更多代码

标签: java xml xpath evaluation


【解决方案1】:

尝试将 XPath 评估更改为

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

或到

Node node = (Node) expr.evaluate(document, XPathConstants.NODE);

取决于预计会找到多少个节点。

【讨论】:

  • 我可以在调试器中看到我得到一个空值(在 XPathConstants.NODESET 或 XPathConstants.NODE 中),无论它是否是节点列表
  • 您的代码中的表达式 if (nodes.item(i).getNodeValue() != null) 返回 false,因为类 org.w3c.Node 的方法 getNodeValue() 为 Node.ELEMENT_NODE 返回 null,请参阅文档:docs.oracle.com/javase/8/docs/api/org/w3c/dom/Node.html
  • 感谢您的回答,我必须添加类似 nodes.item(0).getAttributes().getNamedItem("name")) 的内容才能获得属性“name”的结果。你帮了我!
  • 为此,您可以将 XPath 更改为 //field[@name='a' and @class='b']/@name。然后它将返回满足给定条件的元素的“名称”属性的值。
猜你喜欢
  • 2011-05-30
  • 2021-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-01
相关资源
最近更新 更多