# Java XPath 表达式示例

> 原文： [https://howtodoinjava.com/xml/java-xpath-expression-examples/](https://howtodoinjava.com/xml/java-xpath-expression-examples/)

[Java xpath](https://howtodoinjava.com/xml/how-to-work-with-xpaths-in-java-with-examples/) 表达式示例，通过求值这些表达式从 XML 文档中提取信息。 我们将学习获取有关匹配属性值，匹配字段值，`contains()`表达式等的信息。

## 1\. XPath 查询示例

#### 1.1 输入 XML 文件

首先查看我们将读取的 XML 文件，然后使用 **xpath 查询**从中获取信息。

```java
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<employees>
    <employee id="1">
        <firstName>Lokesh</firstName>
        <lastName>Gupta</lastName>
        <department>
            <id>101</id>
            <name>IT</name>
        </department>
    </employee>
    <employee id="2">
        <firstName>Brian</firstName>
        <lastName>Schultz</lastName>
        <department>
            <id>102</id>
            <name>HR</name>
        </department>
    </employee>
    <employee id="3">
        <firstName>Alex</firstName>
        <lastName>Kolenchisky</lastName>
        <department>
            <id>103</id>
            <name>FINANCE</name>
        </department>
    </employee>
    <employee id="4">
        <firstName>Amit</firstName>
        <lastName>Jain</lastName>
        <department>
            <id>104</id>
            <name>HR</name>
        </department>
    </employee>
    <employee id="5">
        <firstName>David</firstName>
        <lastName>Beckham</lastName>
        <department>
            <id>105</id>
            <name>DEVOPS</name>
        </department>
    </employee>
    <employee id="6">
        <firstName>Virat</firstName>
        <lastName>Kohli</lastName>
        <department>
            <id>106</id>
            <name>DEVOPS</name>
        </department>
    </employee>
    <employee id="7">
        <firstName>John</firstName>
        <lastName>Wick</lastName>
        <department>
            <id>107</id>
            <name>IT</name>
        </department>
    </employee>
    <employee id="8">
        <firstName>Mike</firstName>
        <lastName>Anderson</lastName>
        <department>
            <id>108</id>
            <name>HR</name>
        </department>
    </employee>
    <employee id="9">
        <firstName>Bob</firstName>
        <lastName>Sponge</lastName>
        <department>
            <id>109</id>
            <name>FINANCE</name>
        </department>
    </employee>
    <employee id="10">
        <firstName>Gary</firstName>
        <lastName>Kasporov</lastName>
        <department>
            <id>110</id>
            <name>IT</name>
        </department>
    </employee>
</employees>

```

#### 1.2 XPath 表达式

现在来看几个有关如何构建 xpath 以便基于字段和属性的各种条件获取信息的示例。

| 描述 | XPath | 结果 |
| --- | --- | --- |
| 获取所有员工姓名 | `/employees/employee/firstName/text()` | `[Lokesh, Brian, Alex, Amit, David, Virat, John, Mike, Bob, Gary]` |
| 获取所有部门名称 | `/employees/employee/department/name/text()` | `[IT, HR, FINANCE, HR, DEVOPS, DEVOPS, IT, HR, FINANCE, IT]` |
| 获取所有 IT 员工 | `/employees/employee[department/name='IT']/firstName/text()` | `[Lokesh, John, Gary]` |
| 按编号获取员工 | `/employees/employee[@id=4]/firstName/text()` | `	[Amit]` |
| 取得 ID 大于 6 的员工 | `/employees/employee[@id>6]/firstName/text()` | `[John, Mike, Bob, Gary]` |
| 获取大卫的部门 | `/employees/employee[firstName = 'David']/department/name/text()` | `[DEVOPS]` |
| 获取所有员工 ID | `/employees/employee/@id` | `	[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]` |
| 获取人力资源部门的所有员工 ID | `/employees/employee[department/name='HR']/@id` | `	[2, 4, 8]` |
| 获取员工“`Alex`”编号 | `/employees/employee[firstName='Alex']/@id` | `[3]` |
| 获取大于 5 的员工 ID | `/employees/employee/@id[. > 5]` | `[6, 7, 8, 9, 10]` |
| 获取其 ID 包含“1”的员工 | `/employees/employee[contains(@id,'1')]/firstName/text()` | `[Lokesh, Gary]` |
| 获取其 ID 包含 1 的员工 | `descendant-or-self::*[contains(@id,'1')]/firstName/text()` | `[Lokesh, Gary]` |

## 2.求值 xpath 表达式的 Java 示例

让我们看一下用于求值以上 xpath 表达式的代码。

```java
package com.howtodoinjava.demo;

import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
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;

public class XPathExample 
{
	public static void main(String[] args) throws Exception 
	{
		//Get DOM Node for XML
		String fileName= "employees.xml";
		Document document = getDocument(fileName);

		String xpathExpression = "";

		/*******Get attribute values using xpath******/

		//Get all employee ids
		xpathExpression = "/employees/employee/@id";
		System.out.println( evaluateXPath(document, xpathExpression) );

		//Get all employee ids in HR department
		xpathExpression = "/employees/employee[department/name='HR']/@id";
		System.out.println( evaluateXPath(document, xpathExpression) );

		//Get employee id of 'Alex'
		xpathExpression = "/employees/employee[firstName='Alex']/@id";
		System.out.println( evaluateXPath(document, xpathExpression) );

		//Get employee ids greater than 5
		xpathExpression = "/employees/employee/@id[. > 5]";
		System.out.println( evaluateXPath(document, xpathExpression) );

		//Get employee whose id contains 1
		xpathExpression = "/employees/employee[contains(@id,'1')]/firstName/text()";
		System.out.println( evaluateXPath(document, xpathExpression) );

		//Get employee whose id contains 1
		xpathExpression = "descendant-or-self::*[contains(@id,'1')]/firstName/text()";
		System.out.println( evaluateXPath(document, xpathExpression) );
	}

	private static List<String> evaluateXPath(Document document, String xpathExpression) throws Exception 
	{
		// Create XPathFactory object
		XPathFactory xpathFactory = XPathFactory.newInstance();

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

		List<String> values = new ArrayList<>();
		try 
		{
			// Create XPathExpression object
			XPathExpression expr = xpath.compile(xpathExpression);

			// Evaluate expression result on XML document
			NodeList nodes = (NodeList) expr.evaluate(document, XPathConstants.NODESET);

			for (int i = 0; i < nodes.getLength(); i++) {
				values.add(nodes.item(i).getNodeValue());
			}

		} catch (XPathExpressionException e) {
			e.printStackTrace();
		}
		return values;
	}

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

```

程序输出：

```java
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[2, 4, 8]
[3]
[6, 7, 8, 9, 10]
[Lokesh, Gary]
[Lokesh, Gary]

```

> **XPath 表达式不是线程安全的**。 确保在任何给定时间不从多个线程使用一个`XPathExpression`对象是应用的责任，并且在调用求值方法时，应用可能不会递归调用求值方法。

## 3.模型类

```java
@XmlRootElement(name="employees")
@XmlAccessorType(XmlAccessType.FIELD)
public class Employees implements Serializable
{
	private static final long serialVersionUID = 1L;

	@XmlElement(name="employee")
	private List<Employee> employees;

	public List<Employee> getEmployees() {
		if(employees == null) {
			employees = new ArrayList<Employee>();
		}
		return employees;
	}

	public void setEmployees(List<Employee> employees) {
		this.employees = employees;
	}

	@Override
	public String toString() {
		return "Employees [employees=" + employees + "]";
	}
}

```

```java
@XmlRootElement(name="employee")
@XmlAccessorType(XmlAccessType.FIELD)
public class Employee implements Serializable {

	private static final long serialVersionUID = 1L;

	@XmlAttribute
	private Integer id;
	private String firstName;
	private String lastName;
	private Department department;

	public Employee() {
		super();
	}

	public Employee(int id, String fName, String lName, Department department) {
		super();
		this.id = id;
		this.firstName = fName;
		this.lastName = lName;
		this.department = department;
	}

	//Setters and Getters

	@Override
	public String toString() {
		return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", department=" + department + "]";
	}
}

```

```java
@XmlRootElement(name="department")
@XmlAccessorType(XmlAccessType.FIELD)
public class Department implements Serializable {

	private static final long serialVersionUID = 1L;

	Integer id;
	String name;

	public Department() {
		super();
	}

	public Department(Integer id, String name) {
		super();
		this.id = id;
		this.name = name;
	}

	//Setters and Getters

	@Override
	public String toString() {
		return "Department [id=" + id + ", name=" + name + "]";
	}
}

```

将我的问题放在评论部分。

学习愉快！

参考文献：

[`XPathFactory` Java 文件](https://docs.oracle.com/javase/7/docs/api/javax/xml/xpath/XPathFactory.html)

[XPath Java 文件](https://docs.oracle.com/javase/7/docs/api/javax/xml/xpath/XPath.html)

[XPathExpression Java 文件](https://docs.oracle.com/javase/7/docs/api/javax/xml/xpath/XPathExpression.html)

[org.w3c.dom.Document Java 文件](https://docs.oracle.com/javase/7/docs/api/org/w3c/dom/Document.html)