如何使用 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 XMLString fileName= "employees.xml";Document document = getDocument(fileName);String xpathExpression = "";/*******Get attribute values using xpath******///Get all employee idsxpathExpression = "/employees/employee/@id";System.out.println( evaluateXPath(document, xpathExpression) );//Get all employee ids in HR departmentxpathExpression = "/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 5xpathExpression = "/employees/employee/@id[. > 5]";System.out.println( evaluateXPath(document, xpathExpression) );//Get employee whose id contains 1xpathExpression = "/employees/employee[contains(@id,'1')]/firstName/text()";System.out.println( evaluateXPath(document, xpathExpression) );//Get employee whose id contains 1xpathExpression = "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 objectXPathFactory xpathFactory = XPathFactory.newInstance();// Create XPath objectXPath xpath = xpathFactory.newXPath();List<String> values = new ArrayList<>();try{// Create XPathExpression objectXPathExpression expr = xpath.compile(xpathExpression);// Evaluate expression result on XML documentNodeList 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;}@Overridepublic String toString() {return "Employees [employees=" + employees + "]";}}
@XmlRootElement(name="employee")@XmlAccessorType(XmlAccessType.FIELD)public class Employee implements Serializable {private static final long serialVersionUID = 1L;@XmlAttributeprivate 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@Overridepublic 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@Overridepublic String toString() {return "Department [id=" + id + ", name=" + name + "]";}}
向我提供有关如何使用 xpath 查找具有属性值的 xml 元素的问题。
学习愉快!
