原文: https://howtodoinjava.com/xml/jdom2-read-parse-xml-examples/

JDOM 解析器可用于在更新 XML 内容后用于读取 XML,解析 XML 和写入 XML 文件。 它将 JDOM2 文档存储在内存中,以读取和修改其值。

将 XML 文档加载到内存中后,JDOM2 维护严格的父子类型关系。 父类型的 JDOM 实例(父)具有访问其内容的方法,子类型的 JDOM 实例(内容)具有访问其父对象的方法。

  1. Table of Contents
  2. Project Structure
  3. JDOM2 Maven Dependency
  4. Create JDOM2 Document
  5. Read and filter XML content
  6. Read XML Content with XPath
  7. Complete Example
  8. 源码下载

项目结构

请创建此文件夹结构以执行示例。 这是在 Eclipse 中创建的简单 Maven 项目

Java JDOM2 – XML 读取示例 - 图1

项目结构

请注意,我已经使用了 lambda 表达式方法引用,因此您需要配置为使用 JDK 1.8。

JDOM2 Maven 依赖关系

  1. <dependency>
  2. <groupId>org.jdom</groupId>
  3. <artifactId>jdom2</artifactId>
  4. <version>2.0.6</version>
  5. </dependency>

要执行 XPath,您还需要 jaxen。

  1. <dependency>
  2. <groupId>jaxen</groupId>
  3. <artifactId>jaxen</artifactId>
  4. <version>1.1.6</version>
  5. </dependency>

创建 JDOM2 文档

您可以使用下面列出的任何解析器创建org.jdom2.Document实例。 它们都解析 XML 并返回内存中的 JDOM 文档

  1. 使用 DOM 解析器

  1. private static Document getDOMParsedDocument(final String fileName)
  2. {
  3. Document document = null;
  4. try
  5. {
  6. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  7. //If want to make namespace aware.
  8. //factory.setNamespaceAware(true);
  9. DocumentBuilder documentBuilder = factory.newDocumentBuilder();
  10. org.w3c.dom.Document w3cDocument = documentBuilder.parse(fileName);
  11. document = new DOMBuilder().build(w3cDocument);
  12. }
  13. catch (IOException | SAXException | ParserConfigurationException e)
  14. {
  15. e.printStackTrace();
  16. }
  17. return document;
  18. }
  1. 使用 SAX 解析器

  1. private static Document getSAXParsedDocument(final String fileName)
  2. {
  3. SAXBuilder builder = new SAXBuilder();
  4. Document document = null;
  5. try
  6. {
  7. document = builder.build(fileName);
  8. }
  9. catch (JDOMException | IOException e)
  10. {
  11. e.printStackTrace();
  12. }
  13. return document;
  14. }
  1. 使用 StAX 解析器

  1. private static Document getStAXParsedDocument(final String fileName)
  2. {
  3. Document document = null;
  4. try
  5. {
  6. XMLInputFactory factory = XMLInputFactory.newFactory();
  7. XMLEventReader reader = factory.createXMLEventReader(new FileReader(fileName));
  8. StAXEventBuilder builder = new StAXEventBuilder();
  9. document = builder.build(reader);
  10. }
  11. catch (JDOMException | IOException | XMLStreamException e)
  12. {
  13. e.printStackTrace();
  14. }
  15. return document;
  16. }

读取和过滤 XML 内容

我将读取employees.xml文件。

  1. <employees>
  2. <employee id="101">
  3. <firstName>Lokesh</firstName>
  4. <lastName>Gupta</lastName>
  5. <country>India</country>
  6. <department id="25">
  7. <name>ITS</name>
  8. </department>
  9. </employee>
  10. <employee id="102">
  11. <firstName>Brian</firstName>
  12. <lastName>Schultz</lastName>
  13. <country>USA</country>
  14. <department id="26">
  15. <name>DEV</name>
  16. </department>
  17. </employee>
  18. </employees>

读取根节点

使用document.getRootElement()方法。

  1. public static void main(String[] args)
  2. {
  3. String xmlFile = "employees.xml";
  4. Document document = getSAXParsedDocument(xmlFile);
  5. Element rootNode = document.getRootElement();
  6. System.out.println("Root Element :: " + rootNode.getName());
  7. }

输出:

  1. Root Element :: employees

读取属性值

使用Element.getAttributeValue()方法。

  1. public static void main(String[] args)
  2. {
  3. String xmlFile = "employees.xml";
  4. Document document = getSAXParsedDocument(xmlFile);
  5. Element rootNode = document.getRootElement();
  6. rootNode.getChildren("employee").forEach( ReadXMLDemo::readEmployeeNode );
  7. }
  8. private static void readEmployeeNode(Element employeeNode)
  9. {
  10. //Employee Id
  11. System.out.println("Id : " + employeeNode.getAttributeValue("id"));
  12. }

输出:

  1. Id : 101
  2. Id : 102

读取元素值

使用Element.getChildText()Element.getText()方法。

  1. public static void main(String[] args)
  2. {
  3. String xmlFile = "employees.xml";
  4. Document document = getSAXParsedDocument(xmlFile);
  5. Element rootNode = document.getRootElement();
  6. rootNode.getChildren("employee").forEach( ReadXMLDemo::readEmployeeNode );
  7. }
  8. private static void readEmployeeNode(Element employeeNode)
  9. {
  10. //Employee Id
  11. System.out.println("Id : " + employeeNode.getAttributeValue("id"));
  12. //First Name
  13. System.out.println("FirstName : " + employeeNode.getChildText("firstName"));
  14. //Last Name
  15. System.out.println("LastName : " + employeeNode.getChildText("lastName"));
  16. //Country
  17. System.out.println("country : " + employeeNode.getChild("country").getText());
  18. /**Read Department Content*/
  19. employeeNode.getChildren("department").forEach( ReadXMLDemo::readDepartmentNode );
  20. }
  21. private static void readDepartmentNode(Element deptNode)
  22. {
  23. //Department Id
  24. System.out.println("Department Id : " + deptNode.getAttributeValue("id"));
  25. //Department Name
  26. System.out.println("Department Name : " + deptNode.getChildText("name"));
  27. }

Output:

  1. FirstName : Lokesh
  2. LastName : Gupta
  3. country : India
  4. Department Id : 25
  5. Department Name : ITS
  6. FirstName : Brian
  7. LastName : Schultz
  8. country : USA
  9. Department Id : 26
  10. Department Name : DEV

使用 XPath 读取 XML 内容

要使用 xpath 读取任何元素的值集,您需要编译XPathExpression并使用其evaluate()方法。

  1. String xmlFile = "employees.xml";
  2. Document document = getSAXParsedDocument(xmlFile);
  3. XPathFactory xpfac = XPathFactory.instance();
  4. //Read employee ids
  5. XPathExpression<Attribute> xPathA = xpfac.compile("//employees/employee/@id", Filters.attribute());
  6. for (Attribute att : xPathA.evaluate(document))
  7. {
  8. System.out.println("Employee Ids :: " + att.getValue());
  9. }
  10. //Read employee first names
  11. XPathExpression<Element> xPathN = xpfac.compile("//employees/employee/firstName", Filters.element());
  12. for (Element element : xPathN.evaluate(document))
  13. {
  14. System.out.println("Employee First Name :: " + element.getValue());
  15. }

输出:

  1. Employee Ids :: 101
  2. Employee Ids :: 102
  3. Employee First Name :: Lokesh
  4. Employee First Name :: Brian

完整的 JDOM2 XML 读取示例

这是在 Java 中使用 JDOM2 读取 xml 的完整代码

  1. package com.howtodoinjava.demo.jdom2;
  2. import java.io.FileReader;
  3. import java.io.IOException;
  4. import javax.xml.parsers.DocumentBuilder;
  5. import javax.xml.parsers.DocumentBuilderFactory;
  6. import javax.xml.parsers.ParserConfigurationException;
  7. import javax.xml.stream.XMLEventReader;
  8. import javax.xml.stream.XMLInputFactory;
  9. import javax.xml.stream.XMLStreamException;
  10. import org.jdom2.Attribute;
  11. import org.jdom2.Document;
  12. import org.jdom2.Element;
  13. import org.jdom2.JDOMException;
  14. import org.jdom2.filter.Filters;
  15. import org.jdom2.input.DOMBuilder;
  16. import org.jdom2.input.SAXBuilder;
  17. import org.jdom2.input.StAXEventBuilder;
  18. import org.jdom2.xpath.XPathExpression;
  19. import org.jdom2.xpath.XPathFactory;
  20. import org.xml.sax.SAXException;
  21. @SuppressWarnings("unused")
  22. public class ReadXMLDemo
  23. {
  24. public static void main(String[] args)
  25. {
  26. String xmlFile = "employees.xml";
  27. Document document = getSAXParsedDocument(xmlFile);
  28. /**Read Document Content*/
  29. Element rootNode = document.getRootElement();
  30. System.out.println("Root Element :: " + rootNode.getName());
  31. System.out.println("\n=================================\n");
  32. /**Read Employee Content*/
  33. rootNode.getChildren("employee").forEach( ReadXMLDemo::readEmployeeNode );
  34. System.out.println("\n=================================\n");
  35. readByXPath(document);
  36. }
  37. private static void readEmployeeNode(Element employeeNode)
  38. {
  39. //Employee Id
  40. System.out.println("Id : " + employeeNode.getAttributeValue("id"));
  41. //First Name
  42. System.out.println("FirstName : " + employeeNode.getChildText("firstName"));
  43. //Last Name
  44. System.out.println("LastName : " + employeeNode.getChildText("lastName"));
  45. //Country
  46. System.out.println("country : " + employeeNode.getChild("country").getText());
  47. /**Read Department Content*/
  48. employeeNode.getChildren("department").forEach( ReadXMLDemo::readDepartmentNode );
  49. }
  50. private static void readDepartmentNode(Element deptNode)
  51. {
  52. //Department Id
  53. System.out.println("Department Id : " + deptNode.getAttributeValue("id"));
  54. //Department Name
  55. System.out.println("Department Name : " + deptNode.getChildText("name"));
  56. }
  57. private static void readByXPath(Document document)
  58. {
  59. //Read employee ids
  60. XPathFactory xpfac = XPathFactory.instance();
  61. XPathExpression<Attribute> xPathA = xpfac.compile("//employees/employee/@id", Filters.attribute());
  62. for (Attribute att : xPathA.evaluate(document))
  63. {
  64. System.out.println("Employee Ids :: " + att.getValue());
  65. }
  66. XPathExpression<Element> xPathN = xpfac.compile("//employees/employee/firstName", Filters.element());
  67. for (Element element : xPathN.evaluate(document))
  68. {
  69. System.out.println("Employee First Name :: " + element.getValue());
  70. }
  71. }
  72. private static Document getSAXParsedDocument(final String fileName)
  73. {
  74. SAXBuilder builder = new SAXBuilder();
  75. Document document = null;
  76. try
  77. {
  78. document = builder.build(fileName);
  79. }
  80. catch (JDOMException | IOException e)
  81. {
  82. e.printStackTrace();
  83. }
  84. return document;
  85. }
  86. private static Document getStAXParsedDocument(final String fileName)
  87. {
  88. Document document = null;
  89. try
  90. {
  91. XMLInputFactory factory = XMLInputFactory.newFactory();
  92. XMLEventReader reader = factory.createXMLEventReader(new FileReader(fileName));
  93. StAXEventBuilder builder = new StAXEventBuilder();
  94. document = builder.build(reader);
  95. }
  96. catch (JDOMException | IOException | XMLStreamException e)
  97. {
  98. e.printStackTrace();
  99. }
  100. return document;
  101. }
  102. private static Document getDOMParsedDocument(final String fileName)
  103. {
  104. Document document = null;
  105. try
  106. {
  107. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  108. //If want to make namespace aware.
  109. //factory.setNamespaceAware(true);
  110. DocumentBuilder documentBuilder = factory.newDocumentBuilder();
  111. org.w3c.dom.Document w3cDocument = documentBuilder.parse(fileName);
  112. document = new DOMBuilder().build(w3cDocument);
  113. }
  114. catch (IOException | SAXException | ParserConfigurationException e)
  115. {
  116. e.printStackTrace();
  117. }
  118. return document;
  119. }
  120. /*private static String readFileContent(String filePath)
  121. {
  122. StringBuilder contentBuilder = new StringBuilder();
  123. try (Stream<String> stream = Files.lines( Paths.get(filePath), StandardCharsets.UTF_8))
  124. {
  125. stream.forEach(s -> contentBuilder.append(s).append("\n"));
  126. }
  127. catch (IOException e)
  128. {
  129. e.printStackTrace();
  130. }
  131. return contentBuilder.toString();
  132. }*/
  133. }

输出:

  1. Root Element :: employees
  2. =================================
  3. Id : 101
  4. FirstName : Lokesh
  5. LastName : Gupta
  6. country : India
  7. Department Id : 25
  8. Department Name : ITS
  9. Id : 102
  10. FirstName : Brian
  11. LastName : Schultz
  12. country : USA
  13. Department Id : 26
  14. Department Name : DEV
  15. =================================
  16. Employee Ids :: 101
  17. Employee Ids :: 102
  18. Employee First Name :: Lokesh
  19. Employee First Name :: Brian

源代码下载

下载源码

学习愉快!

参考文献:

JDOM 网站

JDOM2 入门