原文: https://howtodoinjava.com/xml/xpath-attribute-evaluate/

如何使用 Java 中的 xpath 获取 xml 中的属性值的简单示例。 我们将学习获取信息以匹配属性值属性值在范围内,xpath 属性contains()等。

1. XPath 属性表达式

1.1 输入 XML 文件

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

  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  2. <employees>
  3. <employee id="1">
  4. <firstName>Lokesh</firstName>
  5. <lastName>Gupta</lastName>
  6. <department>
  7. <id>101</id>
  8. <name>IT</name>
  9. </department>
  10. </employee>
  11. <employee id="2">
  12. <firstName>Brian</firstName>
  13. <lastName>Schultz</lastName>
  14. <department>
  15. <id>102</id>
  16. <name>HR</name>
  17. </department>
  18. </employee>
  19. <employee id="3">
  20. <firstName>Alex</firstName>
  21. <lastName>Kolenchisky</lastName>
  22. <department>
  23. <id>103</id>
  24. <name>FINANCE</name>
  25. </department>
  26. </employee>
  27. <employee id="4">
  28. <firstName>Amit</firstName>
  29. <lastName>Jain</lastName>
  30. <department>
  31. <id>104</id>
  32. <name>HR</name>
  33. </department>
  34. </employee>
  35. <employee id="5">
  36. <firstName>David</firstName>
  37. <lastName>Beckham</lastName>
  38. <department>
  39. <id>105</id>
  40. <name>DEVOPS</name>
  41. </department>
  42. </employee>
  43. <employee id="6">
  44. <firstName>Virat</firstName>
  45. <lastName>Kohli</lastName>
  46. <department>
  47. <id>106</id>
  48. <name>DEVOPS</name>
  49. </department>
  50. </employee>
  51. <employee id="7">
  52. <firstName>John</firstName>
  53. <lastName>Wick</lastName>
  54. <department>
  55. <id>107</id>
  56. <name>IT</name>
  57. </department>
  58. </employee>
  59. <employee id="8">
  60. <firstName>Mike</firstName>
  61. <lastName>Anderson</lastName>
  62. <department>
  63. <id>108</id>
  64. <name>HR</name>
  65. </department>
  66. </employee>
  67. <employee id="9">
  68. <firstName>Bob</firstName>
  69. <lastName>Sponge</lastName>
  70. <department>
  71. <id>109</id>
  72. <name>FINANCE</name>
  73. </department>
  74. </employee>
  75. <employee id="10">
  76. <firstName>Gary</firstName>
  77. <lastName>Kasporov</lastName>
  78. <department>
  79. <id>110</id>
  80. <name>IT</name>
  81. </department>
  82. </employee>
  83. </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对象是应用的责任,并且在调用求值方法时,应用可能不会递归调用求值方法。

  1. package com.howtodoinjava.demo;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import javax.xml.parsers.DocumentBuilder;
  5. import javax.xml.parsers.DocumentBuilderFactory;
  6. import javax.xml.xpath.XPath;
  7. import javax.xml.xpath.XPathConstants;
  8. import javax.xml.xpath.XPathExpression;
  9. import javax.xml.xpath.XPathExpressionException;
  10. import javax.xml.xpath.XPathFactory;
  11. import org.w3c.dom.Document;
  12. import org.w3c.dom.NodeList;
  13. public class XPathExample
  14. {
  15. public static void main(String[] args) throws Exception
  16. {
  17. //Get DOM Node for XML
  18. String fileName= "employees.xml";
  19. Document document = getDocument(fileName);
  20. String xpathExpression = "";
  21. /*******Get attribute values using xpath******/
  22. //Get all employee ids
  23. xpathExpression = "/employees/employee/@id";
  24. System.out.println( evaluateXPath(document, xpathExpression) );
  25. //Get all employee ids in HR department
  26. xpathExpression = "/employees/employee[department/name='HR']/@id";
  27. System.out.println( evaluateXPath(document, xpathExpression) );
  28. //Get employee id of 'Alex'
  29. xpathExpression = "/employees/employee[firstName='Alex']/@id";
  30. System.out.println( evaluateXPath(document, xpathExpression) );
  31. //Get employee ids greater than 5
  32. xpathExpression = "/employees/employee/@id[. > 5]";
  33. System.out.println( evaluateXPath(document, xpathExpression) );
  34. //Get employee whose id contains 1
  35. xpathExpression = "/employees/employee[contains(@id,'1')]/firstName/text()";
  36. System.out.println( evaluateXPath(document, xpathExpression) );
  37. //Get employee whose id contains 1
  38. xpathExpression = "descendant-or-self::*[contains(@id,'1')]/firstName/text()";
  39. System.out.println( evaluateXPath(document, xpathExpression) );
  40. }
  41. private static List<String> evaluateXPath(Document document, String xpathExpression) throws Exception
  42. {
  43. // Create XPathFactory object
  44. XPathFactory xpathFactory = XPathFactory.newInstance();
  45. // Create XPath object
  46. XPath xpath = xpathFactory.newXPath();
  47. List<String> values = new ArrayList<>();
  48. try
  49. {
  50. // Create XPathExpression object
  51. XPathExpression expr = xpath.compile(xpathExpression);
  52. // Evaluate expression result on XML document
  53. NodeList nodes = (NodeList) expr.evaluate(document, XPathConstants.NODESET);
  54. for (int i = 0; i < nodes.getLength(); i++) {
  55. values.add(nodes.item(i).getNodeValue());
  56. }
  57. } catch (XPathExpressionException e) {
  58. e.printStackTrace();
  59. }
  60. return values;
  61. }
  62. private static Document getDocument(String fileName) throws Exception
  63. {
  64. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  65. factory.setNamespaceAware(true);
  66. DocumentBuilder builder = factory.newDocumentBuilder();
  67. Document doc = builder.parse(fileName);
  68. return doc;
  69. }
  70. }

程序输出:

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

2.2 模型类

  1. @XmlRootElement(name="employees")
  2. @XmlAccessorType(XmlAccessType.FIELD)
  3. public class Employees implements Serializable
  4. {
  5. private static final long serialVersionUID = 1L;
  6. @XmlElement(name="employee")
  7. private List<Employee> employees;
  8. public List<Employee> getEmployees() {
  9. if(employees == null) {
  10. employees = new ArrayList<Employee>();
  11. }
  12. return employees;
  13. }
  14. public void setEmployees(List<Employee> employees) {
  15. this.employees = employees;
  16. }
  17. @Override
  18. public String toString() {
  19. return "Employees [employees=" + employees + "]";
  20. }
  21. }
  1. @XmlRootElement(name="employee")
  2. @XmlAccessorType(XmlAccessType.FIELD)
  3. public class Employee implements Serializable {
  4. private static final long serialVersionUID = 1L;
  5. @XmlAttribute
  6. private Integer id;
  7. private String firstName;
  8. private String lastName;
  9. private Department department;
  10. public Employee() {
  11. super();
  12. }
  13. public Employee(int id, String fName, String lName, Department department) {
  14. super();
  15. this.id = id;
  16. this.firstName = fName;
  17. this.lastName = lName;
  18. this.department = department;
  19. }
  20. //Setters and Getters
  21. @Override
  22. public String toString() {
  23. return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", department="
  24. + department + "]";
  25. }
  26. }
  1. @XmlRootElement(name="department")
  2. @XmlAccessorType(XmlAccessType.FIELD)
  3. public class Department implements Serializable {
  4. private static final long serialVersionUID = 1L;
  5. Integer id;
  6. String name;
  7. public Department() {
  8. super();
  9. }
  10. public Department(Integer id, String name) {
  11. super();
  12. this.id = id;
  13. this.name = name;
  14. }
  15. //Setters and Getters
  16. @Override
  17. public String toString() {
  18. return "Department [id=" + id + ", name=" + name + "]";
  19. }
  20. }

向我提供有关如何使用 xpath 查找具有属性值的 xml 元素的问题。

学习愉快!