。# Java读取XML文件详解:4种常用方法与实例教程
一、引言:为什么要学Java读取XML?
)
配置文件(如Spring框架的applicationContext.xml?);
数据交换(如Web服务中的SOAP协议);
存储结构化数据(如导出报表、保存用户配置)。
将Java的XML解析能力充分的掌握起来,无疑对我们日常的开发工作,尤其是对我们接触的各种web项目的开发都将起到非常大的作用.。)。
二、XML基础:先搞懂这些概念
在开始之前,先回顾一下XML的核心结构:
根元素:XML文档的顶级节点(如<students>);
子元素:根元素下的节点(如<student>);
属性:元素的附加信息(如<student id="1">中的id);
文本内容:元素中的值(如<name>张三</name>中的张三)。
例如,一个简单的XML文件(students.xml?):
<?xml version="1.0" encoding="UTF-8"?><students> <student id="1"> <name>张三</name> <age>20</age> </student> <student id="2"> <name>李四</name> <age>22</age> </student></students>
三、Java读取XML的4种常用方法
1. DOM解析(自带,适合小文件)
原理:将整个XML文档加载到内存中,形成一棵DOM树(Document Object Model),开发者可以通过遍历树结构来读取节点内容。
步骤:
创建DocumentBuilderFactory实例;
创建DocumentBuilder实例;
解析XML文件得到Document对象;
遍历DOM树,读取节点信息。
实例代码:
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import java.io.File;
public class DOMExample {
public static void main(String[] args) {
try {
// 1. 加载XML文件 File xmlFile = new File("students.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance;
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder;
Document doc = dBuilder.parse(xmlFile);
// 2. 规范化文档(去除空白节点) doc.getDocumentElement.normalize;
// 3. 读取根元素 System.out.println(" 根元素:" + doc.getDocumentElement.getNodeName);
// 4. 遍历子元素(student) NodeList studentList = doc.getElementsByTagName("student");
for (int i = 0; i < studentList.getLength; i++) {
Node node = studentList.item(i);
if (node.getNodeType == Node.ELEMENT_NODE) {
Element studentElement = (Element) node;
// 读取属性(id) String studentId = studentElement.getAttribute("id");
// 读取子元素(name、age) String name = studentElement.getElementsByTagName("name").item.getTextContent;
String age = studentElement.getElementsByTagName("age").item.getTextContent;
System.out.println(" 学生ID:" + studentId);
System.out.println(" 姓名:" + name);
System.out.println(" 年龄:" + age);
System.out.println("-------------------");
}
}
} catch (Exception e) {
e.printStackTrace;
}
}
}
优缺点:
? 优点:直观易懂,支持随机访问(可修改节点内容);
? 缺点:内存占用大(加载整个文档),不适合大文件(如100MB以上的XML)。
2. SAX解析(自带,适合大文件)
通过以事件的驱动下对XML的逐行的解析将其转化为开发者能够通过监听相应的事件来获取所需的数据,从而大大提高了开发的效率和灵活性.。
步骤:
创建SAXParserFactory实例;
创建SAXParser实例;
定义DefaultHandler子类,重写事件处理方法(如startElement、endElement、characters);
解析XML文件。
实例代码:
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;
public class SAXExample {
public static void main(String[] args) {
try {
// 1. 创建SAX解析器 SAXParserFactory factory = SAXParserFactory.newInstance;
SAXParser saxParser = factory.newSAXParser;
// 2. 定义事件处理器 DefaultHandler handler = new DefaultHandler {
boolean isName = false;
boolean isAge = false;
// 开始元素事件(如<student>、<name>) @Override public void startElement(String uri, String localName, String qName, Attributes attributes) {
if (qName.equals("student")) {
// 读取student元素的id属性 String studentId = attributes.getValue("id");
System.out.println(" 学生ID:" + studentId);
} else if (qName.equals("name")) {
isName = true;
} else if (qName.equals("age")) {
isAge = true;
}
}
// 文本内容事件(如“张三”、“20”) @Override public void characters(char[] ch, int start, int length) {
if (isName) {
System.out.println(" 姓名:" + new String(ch, start, length));
isName = false;
} else if (isAge) {
System.out.println(" 年龄:" + new String(ch, start, length));
isAge = false;
}
}
// 结束元素事件(如</student>、</name>) @Override public void endElement(String uri, String localName, String qName) {
if (qName.equals("student")) {
System.out.println("-------------------");
}
}
};
// 3. 解析XML文件 saxParser.parse("students.xml", handler);
} catch (Exception e) {
e.printStackTrace;
}
}
}
优缺点:
? 优点:内存占用极小(逐行读取),适合大文件;
? 缺点:编程复杂(需要处理事件),不支持随机访问(不能修改节点内容)。
3. DOM4J解析(第三方,推荐使用)
)。
步骤:
导入DOM4J依赖(Maven):
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.4</version>
</dependency>
``` ```
创建SAXReader实例;
读取XML文件得到Document对象;
遍历节点或使用XPath查询。
实例代码:
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.util.List;
public class DOM4JExample {
public static void main(String[] args) {
try {
// 1. 创建SAXReader SAXReader reader = new SAXReader;
// 2. 读取XML文件 Document doc = reader.read(new File("students.xml"));
// 3. 获取根元素 Element root = doc.getRootElement;
System.out.println(" 根元素:" + root.getName);
// 4. 遍历子元素(student) List<Element> studentList = root.elements("student");
for (Element student : studentList) {
// 读取属性(id) String studentId = student.attributeValue("id");
// 读取子元素(name、age) String name = student.elementText("name");
String age = student.elementText("age");
System.out.println(" 学生ID:" + studentId);
System.out.println(" 姓名:" + name);
System.out.println(" 年龄:" + age);
System.out.println("-------------------");
}
// 5. 使用XPath查询(可选,更高效) List<Element> xpathResult = root.selectNodes("//student[@id='1']");
System.out.println("XPath 查询结果:" + xpathResult.get.elementText("name"));
} catch (DocumentException e) {
e.printStackTrace;
}
}
}
优缺点:
? 优点:API简洁(如elementText方法)、支持XPath查询、功能强大;
? 缺点:需要导入第三方依赖(但几乎所有Java项目都会用到)。
4. StAX解析(自带,JDK1.6+,灵活)
原理:双向解析(Pull Parsing),既可以像SAX逐行读取,也可以像DOM随机访问,适合需要灵活处理XML的场景。
步骤:
创建XMLInputFactory实例;
创建XMLStreamReader实例;
逐行读取XML事件(如START_ELEMENT、END_ELEMENT);
处理事件并获取数据。
实例代码:
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.events.XMLEvent;
import java.io.FileInputStream;
public class StAXExample {
public static void main(String[] args) {
try {
// 1. 创建StAX解析器 XMLInputFactory factory = XMLInputFactory.newInstance;
XMLStreamReader reader = factory.createXMLStreamReader(new FileInputStream("students.xml"));
// 2. 逐行读取事件 while (reader.hasNext) {
int eventType = reader.next;
switch (eventType) {
// 开始元素事件(如<student>、<name>) case XMLStreamReader.START_ELEMENT:
String elementName = reader.getLocalName;
if (elementName.equals("student")) {
// 读取student元素的id属性 String studentId = reader.getAttributeValue(null, "id");
System.out.println(" 学生ID:" + studentId);
} else if (elementName.equals("name")) {
// 读取name元素的文本内容(需要调用next获取) String name = reader.getElementText;
System.out.println(" 姓名:" + name);
} else if (elementName.equals("age")) {
String age = reader.getElementText;
System.out.println(" 年龄:" + age);
}
break;
// 结束元素事件(如</student>) case XMLStreamReader.END_ELEMENT:
if (reader.getLocalName.equals("student")) {
System.out.println("-------------------");
}
break;
}
}
} catch (Exception e) {
e.printStackTrace;
}
}
}
优缺点:
? 优点:灵活(可控制解析流程)、内存占用小;
? 缺点:编程稍复杂(需要处理事件类型)。
四、4种方法对比:如何选择?
根据你的需求和我们的目标,即使将这句话的表格的存在也尽量用更为自然的语言来展现出其用意:为方便大家更快地选出最合适的方法,我们就将各个方法的优劣对比了一下:
DOM
自带
加载整个文档
直观易懂,支持修改
小文件(<10MB)、需要修改节点
SAX
自带
事件驱动,逐行
内存占用极小
大文件(>100MB)、只需读取一次
DOM4J
第三方
基于DOM
API简洁,支持XPath
大部分场景(推荐使用)
StAX
自带(JDK1.6+)
双向解析
灵活控制解析流程
需要灵活处理的场景(如部分读取)
五、总结:最佳实践
小文件:优先选择DOM4J(API简洁)或DOM(直观);
大文件:优先选择SAX(内存占用小)或StAX(灵活);
需要修改XML:选择DOM或DOM4J(支持节点修改);
需要高效查询:选择DOM4J(支持XPath)。
六、互动:你用过哪种方法?
根据对Java读取XML的四种常用方法的深入的梳理不难发现各自都有其特点的同时也都有其相对应的适用场景,那么在我们的日常的项目的开发中又用过哪种呢?在实际的开发中我们都可能会遇到各种各样的问题,所以也就更应该在下面的评论区一起对这个问题的探讨、互相的交流、共同的解决!
衷心感谢您的阅读支持,对本文的点赞和收藏也将是我继续探索、更新的最大动力,希望能得到您的更多的支持和鼓励!
通过对上述的实例代码的深入的调试和优化,我们最终将其封装成一个可用的的工具,方便广大开发者在实际的项目中更好的地将其运用到实际的开发中去。我们后面还会对XML的更多的操作技巧做详细的介绍,敬请期待!。)