原文: https://howtodoinjava.com/xml/read-xml-dom-parser-example/

在此 Java xml 解析器教程中,学习用 Java 中的 DOM 解析器读取 xml。 DOM 解析器旨在将 XML 作为内存中的对象图(树状结构)使用 – 称为“文档对象模型(DOM)”。

首先,解析器遍历输入的 XML 文件并创建与 XML 文件中的节点相对应的 DOM 对象。 这些 DOM 对象以树状结构链接在一起。 一旦解析器完成了解析过程,我们就会从中获得这种树状 DOM 对象结构。 现在,我们可以根据需要来回遍历 DOM 结构 - 从中获取/更新/删除数据。

  1. Table of Contents
  2. 1\. DOM Parser API
  3. -Import XML-related packages
  4. -Create a DocumentBuilder
  5. -Create a Document from a file or stream
  6. -Validate Document structure
  7. -Extract the root element
  8. -Examine attributes
  9. -Examine sub-elements
  10. 2\. Read XML with DOM parser
  11. 3\. Read data to POJO objects
  12. 4\. Parse "unknown" xml with DOM parser

阅读更多: DOM 解析器和 SAX 解析器之间的区别

出于示例目的,我们将在所有代码示例中解析 xml 内容。

  1. <employees>
  2. <employee id="111">
  3. <firstName>Lokesh</firstName>
  4. <lastName>Gupta</lastName>
  5. <location>India</location>
  6. </employee>
  7. <employee id="222">
  8. <firstName>Alex</firstName>
  9. <lastName>Gussin</lastName>
  10. <location>Russia</location>
  11. </employee>
  12. <employee id="333">
  13. <firstName>David</firstName>
  14. <lastName>Feezor</lastName>
  15. <location>USA</location>
  16. </employee>
  17. </employees>

1. DOM 解析器 API

让我们记下一些主要步骤,以创建并使用 DOM 解析器来解析 Java 中的 XML 文件。

Java 读取 XML – Java DOM 解析器示例 - 图1

DOM 解析器的实际应用

1.1 导入 dom 解析器包

我们将需要首先在我们的应用中导入 dom 解析器包。

  1. import org.w3c.dom.*;
  2. import javax.xml.parsers.*;
  3. import java.io.*;

1.2 创建DocumentBuilder

下一步是创建DocumentBuilder对象。

  1. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  2. DocumentBuilder builder = factory.newDocumentBuilder();

1.3 从 xml 文件创建Document对象

将 XML 文件读取到Document对象。

  1. Document document = builder.parse(new File( file ));

1.4 验证文件结构

XML 验证是可选的,但最好在开始解析之前进行验证。

  1. Schema schema = null;
  2. try {
  3. String language = XMLConstants.W3C_XML_SCHEMA_NS_URI;
  4. SchemaFactory factory = SchemaFactory.newInstance(language);
  5. schema = factory.newSchema(new File(name));
  6. } catch (Exception e) {
  7. e.printStackStrace();
  8. }
  9. Validator validator = schema.newValidator();
  10. validator.validate(new DOMSource(document));

1.5 提取根元素

我们可以使用以下代码从 XML 文档中获取根元素。

  1. Element root = document.getDocumentElement();

1.6 检查属性

我们可以使用以下方法检查 xml 元素属性。

  1. element.getAttribute("attributeName") ; //returns specific attribute
  2. element.getAttributes(); //returns a Map (table) of names/values

1.7 检查子元素

子元素可以以下方式查询。

  1. node.getElementsByTagName("subElementName") //returns a list of sub-elements of specified name
  2. node.getChildNodes() //returns a list of all child nodes

2.使用 DOM 解析器读取 XML

在下面的示例代码中,我假设用户已经知道employees.xml文件的结构(它的节点和属性); 因此,示例直接开始获取信息并开始在控制台中打印信息。 在现实生活中的应用中,我们将这些信息用于某些实际目的,而不是在控制台上打印并离开。

  1. //Get Document Builder
  2. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  3. DocumentBuilder builder = factory.newDocumentBuilder();
  4. //Build Document
  5. Document document = builder.parse(new File("employees.xml"));
  6. //Normalize the XML Structure; It's just too important !!
  7. document.getDocumentElement().normalize();
  8. //Here comes the root node
  9. Element root = document.getDocumentElement();
  10. System.out.println(root.getNodeName());
  11. //Get all employees
  12. NodeList nList = document.getElementsByTagName("employee");
  13. System.out.println("============================");
  14. for (int temp = 0; temp < nList.getLength(); temp++)
  15. {
  16. Node node = nList.item(temp);
  17. System.out.println(""); //Just a separator
  18. if (node.getNodeType() == Node.ELEMENT_NODE)
  19. {
  20. //Print each employee's detail
  21. Element eElement = (Element) node;
  22. System.out.println("Employee id : " + eElement.getAttribute("id"));
  23. System.out.println("First Name : " + eElement.getElementsByTagName("firstName").item(0).getTextContent());
  24. System.out.println("Last Name : " + eElement.getElementsByTagName("lastName").item(0).getTextContent());
  25. System.out.println("Location : " + eElement.getElementsByTagName("location").item(0).getTextContent());
  26. }
  27. }

程序输出:

  1. employees
  2. ============================
  3. Employee id : 111
  4. First Name : Lokesh
  5. Last Name : Gupta
  6. Location : India
  7. Employee id : 222
  8. First Name : Alex
  9. Last Name : Gussin
  10. Location : Russia
  11. Employee id : 333
  12. First Name : David
  13. Last Name : Feezor
  14. Location : USA

3.将数据读取到 POJO 对象

现实生活中另一个应用的要求可能是使用上面示例代码中提取的信息填充 DTO 对象。 我写了一个简单的程序来帮助您了解如何轻松完成它。

假设我们必须填充Employee对象,其定义如下。

  1. public class Employee
  2. {
  3. private Integer id;
  4. private String firstName;
  5. private String lastName;
  6. private String location;
  7. //Setters and Getters
  8. @Override
  9. public String toString()
  10. {
  11. return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", location=" + location + "]";
  12. }
  13. }

现在查看示例代码以填充员工对象列表。 就像在代码之间插入几行,然后将值复制到 DTO 而不是控制台中一样简单。

Java 程序,用于使用 DOM 解析器读取 XML 文件。

  1. public class PopulateDTOExamplesWithParsedXML
  2. {
  3. public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException
  4. {
  5. List<Employee> employees = parseEmployeesXML();
  6. System.out.println(employees);
  7. }
  8. private static List<Employee> parseEmployeesXML() throws ParserConfigurationException, SAXException, IOException
  9. {
  10. //Initialize a list of employees
  11. List<Employee> employees = new ArrayList<Employee>();
  12. Employee employee = null;
  13. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  14. DocumentBuilder builder = factory.newDocumentBuilder();
  15. Document document = builder.parse(new File("employees.xml"));
  16. document.getDocumentElement().normalize();
  17. NodeList nList = document.getElementsByTagName("employee");
  18. for (int temp = 0; temp < nList.getLength(); temp++)
  19. {
  20. Node node = nList.item(temp);
  21. if (node.getNodeType() == Node.ELEMENT_NODE)
  22. {
  23. Element eElement = (Element) node;
  24. //Create new Employee Object
  25. employee = new Employee();
  26. employee.setId(Integer.parseInt(eElement.getAttribute("id")));
  27. employee.setFirstName(eElement.getElementsByTagName("firstName").item(0).getTextContent());
  28. employee.setLastName(eElement.getElementsByTagName("lastName").item(0).getTextContent());
  29. employee.setLocation(eElement.getElementsByTagName("location").item(0).getTextContent());
  30. //Add Employee to list
  31. employees.add(employee);
  32. }
  33. }
  34. return employees;
  35. }
  36. }

程序输出。

  1. [Employee [id=111, firstName=Lokesh, lastName=Gupta, location=India],
  2. Employee [id=222, firstName=Alex, lastName=Gussin, location=Russia],
  3. Employee [id=333, firstName=David, lastName=Feezor, location=USA]]

4.使用 DOM 解析器解析“未知” xml

上一个示例显示了在编写代码时,我们如何遍历具有已知或几乎不知道的结构的 XML 文档。 在某些情况下,我们可能必须以某种方式编写代码,以便即使在编码时假定的 XML 结构存在某些差异,程序也必须能够正常运行。

在这里,我们遍历 XML 文档树中存在的所有元素。 我们可以添加我们的知识并修改代码,以便在遍历树时只要获得所需信息,我们就可以使用它。

  1. public class ParseUnknownXMLStructure
  2. {
  3. public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException
  4. {
  5. //Get Document Builder
  6. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  7. DocumentBuilder builder = factory.newDocumentBuilder();
  8. //Build Document
  9. Document document = builder.parse(new File("employees.xml"));
  10. //Normalize the XML Structure; It's just too important !!
  11. document.getDocumentElement().normalize();
  12. //Here comes the root node
  13. Element root = document.getDocumentElement();
  14. System.out.println(root.getNodeName());
  15. //Get all employees
  16. NodeList nList = document.getElementsByTagName("employee");
  17. System.out.println("============================");
  18. visitChildNodes(nList);
  19. }
  20. //This function is called recursively
  21. private static void visitChildNodes(NodeList nList)
  22. {
  23. for (int temp = 0; temp < nList.getLength(); temp++)
  24. {
  25. Node node = nList.item(temp);
  26. if (node.getNodeType() == Node.ELEMENT_NODE)
  27. {
  28. System.out.println("Node Name = " + node.getNodeName() + "; Value = " + node.getTextContent());
  29. //Check all attributes
  30. if (node.hasAttributes()) {
  31. // get attributes names and values
  32. NamedNodeMap nodeMap = node.getAttributes();
  33. for (int i = 0; i < nodeMap.getLength(); i++)
  34. {
  35. Node tempNode = nodeMap.item(i);
  36. System.out.println("Attr name : " + tempNode.getNodeName()+ "; Value = " + tempNode.getNodeValue());
  37. }
  38. if (node.hasChildNodes()) {
  39. //We got more childs; Let's visit them as well
  40. visitChildNodes(node.getChildNodes());
  41. }
  42. }
  43. }
  44. }
  45. }
  46. }

程序输出:

  1. employees
  2. ============================
  3. Node Name = employee; Value =
  4. Lokesh
  5. Gupta
  6. India
  7. Attr name : id; Value = 111
  8. Node Name = firstName; Value = Lokesh
  9. Node Name = lastName; Value = Gupta
  10. Node Name = location; Value = India
  11. Node Name = employee; Value =
  12. Alex
  13. Gussin
  14. Russia
  15. Attr name : id; Value = 222
  16. Node Name = firstName; Value = Alex
  17. Node Name = lastName; Value = Gussin
  18. Node Name = location; Value = Russia
  19. Node Name = employee; Value =
  20. David
  21. Feezor
  22. USA
  23. Attr name : id; Value = 333
  24. Node Name = firstName; Value = David
  25. Node Name = lastName; Value = Feezor
  26. Node Name = location; Value = USA

这就是 Java XML DOM 解析器的概念。 如果不清楚或需要更多说明,请给我评论。

下载源码

学习愉快!

参考:

http://www.w3c.org/DOM/