如何使用 Java 中的 xpath 获取 xml 中的属性值的简单示例。 我们将学习获取信息以匹配属性值,属性值在范围内,xpath 属性contains()
等。
1. XPath 属性表达式
1.1 输入 XML 文件
首先查看我们将读取的 XML 文件,然后使用 xpath 查询从中获取信息。
<?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 | 结果 |
---|---|---|
获取所有员工 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 查找具有属性值的 xml 元素的 Java 示例
我们来看一下用于求值以上 xpath 表达式以选择具有特定属性值的节点的代码。
2.1 XPath 求值示例
要在 Java 中求值 xpath,您需要执行以下步骤:
- 将 XML 文件读取到
org.w3c.dom.Document
中。 - 使用其
newInstance()
静态方法创建XPathFactory
。 - 从
XPathFactory
获取XPath
实例。 该对象提供对 xpath 求值环境和表达式的访问。 - 创建 xpath 表达式字符串。 使用
xpath.compile()
方法将 xpath 字符串转换为XPathExpression
对象。 - 针对第一步中创建的文档实例求值 xpath。 它将返回文档中的 DOM 节点列表。
- 使用
getNodeValue()
方法迭代节点并获得测试值。
XPath 表达式不是线程安全的。 确保在任何给定时间不从多个线程使用一个
XPathExpression
对象是应用的责任,并且在调用求值方法时,应用可能不会递归调用求值方法。
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;
}
}
程序输出:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[2, 4, 8]
[3]
[6, 7, 8, 9, 10]
[Lokesh, Gary]
[Lokesh, Gary]
2.2 模型类
@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 + "]";
}
}
@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 + "]";
}
}
@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 + "]";
}
}
向我提供有关如何使用 xpath 查找具有属性值的 xml 元素的问题。
学习愉快!