Read an XML File using DOM Parser in Java

学习如何使用 Java DOM 解析器 API 读取或解析 XML 文档为字符串、写入文件和转换为 POJO,并提供示例。

DOM Parser in Action

在本Java xml 解析器教程中,学习如何使用 DOM 解析器读取 XML。DOM 解析器旨在将 XML 作为内存中的对象图(树状结构)处理——所谓的“文档对象模型 (DOM)”。

首先,解析器会遍历输入的 XML 文件,并创建与 XML 文件中的节点对应的DOM 对象。这些 DOM 对象以树状结构相互连接。当解析器完成解析过程后,我们会从它那里得到这个树状的 DOM 对象结构。现在我们可以来回遍历 DOM 结构,以便从中获取/更新/删除数据。

其他读取 XML 文件的方式还有使用 SAX 解析器StAX 解析器等。

1. 设置

为了演示,我们将在所有代码示例中解析下面的 XML 文件。

<employees>
    <employee id="111">
        <firstName>Lokesh</firstName>
        <lastName>Gupta</lastName>
        <location>India</location>
    </employee>
    <employee id="222">
        <firstName>Alex</firstName>
        <lastName>Gussin</lastName>
        <location>Russia</location>
    </employee>
    <employee id="333">
        <firstName>David</firstName>
        <lastName>Feezor</lastName>
        <location>USA</location>
    </employee>
</employees>

2. DOM 解析器 API

让我们记录一些广泛的步骤来创建和使用 DOM 解析器来解析 XML 文件

DOM Parser in Action
DOM 解析器在行动

1.1. 导入 dom 解析器包

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

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

1.2. 创建 DocumentBuilder

下一步是创建DocumentBuilder对象。

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

1.3. 从 XML 文件创建 Document 对象

读取 XML 文件到 Document 对象。

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

1.4. 验证文档结构

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

Schema schema = null;
try {

  String language = XMLConstants.W3C_XML_SCHEMA_NS_URI;
  SchemaFactory factory = SchemaFactory.newInstance(language);
  schema = factory.newSchema(new File(name));
} catch (Exception e) {
    e.printStackStrace();
}

Validator validator = schema.newValidator();
validator.validate(new DOMSource(document));

1.5. 提取根元素

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

Element root = document.getDocumentElement();

1.6. 检查属性

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

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

1.7. 检查子元素

可以按照以下方式查询指定Node 的子元素。

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

2. 使用 DOM 解析器读取 XML 文件

在下面的示例代码中,我们假设用户已经了解 employees.xml 文件的结构(它的节点和属性)。 因此,示例直接开始获取信息并将其打印到控制台。 在实际应用中,我们将使用此信息用于某些实际目的,而不是仅仅将其打印到控制台并停止。

public static Document readXMLDocumentFromFile(String fileNameWithPath) throws Exception {

    //Get Document Builder
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();

    //Build Document
    Document document = builder.parse(new File(fileNameWithPath));

    //Normalize the XML Structure; It's just too important !!
    document.getDocumentElement().normalize();

    return document;
}

现在我们可以使用此方法解析 XML 文件并验证内容。

public static void main(String[] args) throws Exception {
    Document document = readXMLDocumentFromFile("c:/temp/employees.xml");

    //Verify XML Content

    //Here comes the root node
    Element root = document.getDocumentElement();
    System.out.println(root.getNodeName());

    //Get all employees
    NodeList nList = document.getElementsByTagName("employee");
    System.out.println("============================");

    for (int temp = 0; temp < nList.getLength(); temp++) {
      Node node = nList.item(temp);
    
      if (node.getNodeType() == Node.ELEMENT_NODE) {
        //Print each employee's detail
        Element eElement = (Element) node;
        System.out.println("\nEmployee id : " + eElement.getAttribute("id"));
        System.out.println("First Name : " + eElement.getElementsByTagName("firstName").item(0).getTextContent());
        System.out.println("Last Name : " + eElement.getElementsByTagName("lastName").item(0).getTextContent());
        System.out.println("Location : " + eElement.getElementsByTagName("location").item(0).getTextContent());
      }
    }
}

程序输出

employees
============================

Employee id : 111
First Name : Lokesh
Last Name : Gupta
Location : India

Employee id : 222
First Name : Alex
Last Name : Gussin
Location : Russia

Employee id : 333
First Name : David
Last Name : Feezor
Location : USA

3. 将 XML 读取到 POJO

另一个实际应用的需求可能是使用上面示例代码中获取的信息填充 DTO 对象。 我编写了一个简单的程序来帮助我们了解如何轻松完成此操作。

假设我们需要填充 Employee 对象,这些对象定义如下。

public class Employee {

   private Integer id;
   private String firstName;
   private String lastName;
   private String location;

   //Setters, Getters and toString()
}

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

public static List<Employee> parseXmlToPOJO(String fileName) throws Exception {

    List<Employee> employees = new ArrayList<Employee>();

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document document = builder.parse(new File(fileName));
    document.getDocumentElement().normalize();

    NodeList nList = document.getElementsByTagName("employee");

    for (int temp = 0; temp < nList.getLength(); temp++) {
      
      Node node = nList.item(temp);
      if (node.getNodeType() == Node.ELEMENT_NODE) {
        
        Element eElement = (Element) node;
        Employee employee = new Employee();
        employee.setId(Integer.parseInt(eElement.getAttribute("id")));
        employee.setFirstName(eElement.getElementsByTagName("firstName").item(0).getTextContent());
        employee.setLastName(eElement.getElementsByTagName("lastName").item(0).getTextContent());
        employee.setLocation(eElement.getElementsByTagName("location").item(0).getTextContent());

        //Add Employee to list
        employees.add(employee);
      }
    }
    return employees;
}

4. 使用NamedNodeMap 解析“未知” XML

前面的示例展示了我们如何遍历使用已知或略知结构解析的 XML 文档,同时您编写代码。 在某些情况下,我们可能需要以这样一种方式编写代码,即使在编码时 XML 结构存在一些差异,程序也必须能够正常工作而不会发生故障。

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

private static void visitChildNodes(NodeList nList) {

    for (int temp = 0; temp < nList.getLength(); temp++) {
      
      Node node = nList.item(temp);
      if (node.getNodeType() == Node.ELEMENT_NODE) {
        
        System.out.println("Node Name = " + node.getNodeName() + "; Value = " + node.getTextContent());
        //Check all attributes
        if (node.hasAttributes()) {
          
          // get attributes names and values
          NamedNodeMap nodeMap = node.getAttributes();
          for (int i = 0; i < nodeMap.getLength(); i++) {
            
            Node tempNode = nodeMap.item(i);
            System.out.println("Attr name : " + tempNode.getNodeName() + "; Value = " + tempNode.getNodeValue());
          }
          if (node.hasChildNodes()) {
            //We got more children; Let's visit them as well
            visitChildNodes(node.getChildNodes());
          }
        }
      }
    }
}

程序输出。

employees
============================
Node Name = employee; Value =
        Lokesh
        Gupta
        India

Attr name : id; Value = 111
Node Name = firstName; Value = Lokesh
Node Name = lastName; Value = Gupta
Node Name = location; Value = India
Node Name = employee; Value =
        Alex
        Gussin
        Russia

Attr name : id; Value = 222
Node Name = firstName; Value = Alex
Node Name = lastName; Value = Gussin
Node Name = location; Value = Russia
Node Name = employee; Value =
        David
        Feezor
        USA

Attr name : id; Value = 333
Node Name = firstName; Value = David
Node Name = lastName; Value = Feezor
Node Name = location; Value = USA

关于 Java XML DOM 解析器 的所有了解就到此为止。 如果您对某些内容不清楚或需要更多说明,请留下评论。

祝您学习愉快!!

Github 上的源代码

评论

订阅
通知
26 条评论
最多投票
最新 最旧
内联反馈
查看所有评论

关于我们

HowToDoInJava 提供 Java 和相关技术的教程和操作指南。

它还分享最佳实践、算法和解决方案以及经常被问到的面试题。

我们的博客

REST API 教程

关注我们