如何在 Java 中使用 XPath 读取 XML

2022-08-31 05:13:47

我想在Java中使用XPath读取XML数据,因此对于我收集的信息,我无法根据我的要求解析XML。

这是我想做的:

通过其URL从在线获取XML文件,然后使用XPath解析它,我想在其中创建两个方法。一种是我输入特定的节点属性ID,结果我得到所有的子节点,第二种是假设我只想获取特定的子节点值。

<?xml version="1.0"?>
<howto>
  <topic name="Java">
      <url>http://www.rgagnonjavahowto.htm</url>
  <car>taxi</car>
  </topic>
  <topic name="PowerBuilder">
       <url>http://www.rgagnon/pbhowto.htm</url>
       <url>http://www.rgagnon/pbhowtonew.htm</url>
  </topic>
  <topic name="Javascript">
        <url>http://www.rgagnon/jshowto.htm</url>
  </topic>
 <topic name="VBScript">
       <url>http://www.rgagnon/vbshowto.htm</url>
 </topic>
 </howto>

在上面的例子中,如果我通过@name搜索,我想读取所有元素,还有一个函数,我只想从@name'Javascript'只返回一个节点元素。


答案 1

你需要一些类似这样的东西:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(<uri_as_string>);
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile(<xpath_expression>);

然后,在该代码中定义的文档和预期的返回类型中调用传递,并将结果强制转换为结果的对象类型。expr.evaluate()

如果您需要有关特定XPath表达式的帮助,则可能应该将其作为单独的问题提出(除非这是您在这里首先提出的问题 - 我理解您的问题是如何在Java中使用API)。

编辑:(对注释的响应):此 XPath 表达式将为您提供 PowerBuilder 下第一个 URL 元素的文本:

/howto/topic[@name='PowerBuilder']/url/text()

这将为您提供第二个:

/howto/topic[@name='PowerBuilder']/url[2]/text()

你可以通过以下代码获得:

expr.evaluate(doc, XPathConstants.STRING);

如果您不知道给定节点中有多少个URL,那么您应该执行以下操作:

XPathExpression expr = xpath.compile("/howto/topic[@name='PowerBuilder']/url");
NodeList nl = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);

然后循环访问 NodeList。


答案 2

你可以试试这个。

XML 文档

另存为 。employees.xml

<?xml version="1.0" encoding="UTF-8"?>
<Employees>
    <Employee id="1">
        <age>29</age>
        <name>Pankaj</name>
        <gender>Male</gender>
        <role>Java Developer</role>
    </Employee>
    <Employee id="2">
        <age>35</age>
        <name>Lisa</name>
        <gender>Female</gender>
        <role>CEO</role>
    </Employee>
    <Employee id="3">
        <age>40</age>
        <name>Tom</name>
        <gender>Male</gender>
        <role>Manager</role>
    </Employee>
    <Employee id="4">
        <age>25</age>
        <name>Meghan</name>
        <gender>Female</gender>
        <role>Manager</role>
    </Employee>
</Employees>

解析器类

该类具有以下方法

  • 列表项
  • 将返回输入 ID 的雇员姓名的方法。
  • 一种方法,它将返回年龄大于输入年龄的雇员姓名列表。
  • 将返回女性员工姓名列表的方法。

源码

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;


public class Parser {

    public static void main(String[] args) {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        DocumentBuilder builder;
        Document doc = null;
        try {
            builder = factory.newDocumentBuilder();
            doc = builder.parse("employees.xml");

            // Create XPathFactory object
            XPathFactory xpathFactory = XPathFactory.newInstance();

            // Create XPath object
            XPath xpath = xpathFactory.newXPath();

            String name = getEmployeeNameById(doc, xpath, 4);
            System.out.println("Employee Name with ID 4: " + name);

            List<String> names = getEmployeeNameWithAge(doc, xpath, 30);
            System.out.println("Employees with 'age>30' are:" + Arrays.toString(names.toArray()));

            List<String> femaleEmps = getFemaleEmployeesName(doc, xpath);
            System.out.println("Female Employees names are:" +
                    Arrays.toString(femaleEmps.toArray()));

        } catch (ParserConfigurationException | SAXException | IOException e) {
            e.printStackTrace();
        }

    }


    private static List<String> getFemaleEmployeesName(Document doc, XPath xpath) {
        List<String> list = new ArrayList<>();
        try {
            //create XPathExpression object
            XPathExpression expr =
                xpath.compile("/Employees/Employee[gender='Female']/name/text()");
            //evaluate expression result on XML document
            NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
            for (int i = 0; i < nodes.getLength(); i++)
                list.add(nodes.item(i).getNodeValue());
        } catch (XPathExpressionException e) {
            e.printStackTrace();
        }
        return list;
    }


    private static List<String> getEmployeeNameWithAge(Document doc, XPath xpath, int age) {
        List<String> list = new ArrayList<>();
        try {
            XPathExpression expr =
                xpath.compile("/Employees/Employee[age>" + age + "]/name/text()");
            NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
            for (int i = 0; i < nodes.getLength(); i++)
                list.add(nodes.item(i).getNodeValue());
        } catch (XPathExpressionException e) {
            e.printStackTrace();
        }
        return list;
    }


    private static String getEmployeeNameById(Document doc, XPath xpath, int id) {
        String name = null;
        try {
            XPathExpression expr =
                xpath.compile("/Employees/Employee[@id='" + id + "']/name/text()");
            name = (String) expr.evaluate(doc, XPathConstants.STRING);
        } catch (XPathExpressionException e) {
            e.printStackTrace();
        }

        return name;
    }

}

推荐