赞
踩
XML (eXtensible Markup Language)指可扩展标记语言,标准通用标记语言的子集,可以标记数据、定义数据类型,可以允许自定义标记语言进行数据承载,通常被用来传输和存储数据,定义也简单,遵循核心DTD(文档类型定义)语法约束。
以如下方式开头,用来表述文档的一些信息:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
例如:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<site>
<name>CSDN博客网站</name>
<url>https://blog.csdn.net/</url>
<desc>技术学习网站</desc>
</site>
其中<site>、<name>、<url>、<desc>表示标签名称,内容表示标签对应的值。
XML 具有平台无关性、语言无关性、系统无关性等特点,因而成为系统之间一种通用的便利的数据交换格式,不同的编程语言,解析 XML 的逻辑基本相似,只不过实现的语法稍有不同。而对于Java 程序解析 XML 文件,主流有四种方式:
DOM 解析
SAX 解析
JDOM 解析
DOM4J 解析
下面以如下 XML 文件为例,分别介绍每种方式的解析实现。
<?xml version="1.0" encoding="utf-8" ?>
<class>
<student id="1">
<name>张三</name>
<gender>男</gender>
<age>26</age>
</student>
<student id="2">
<name>里斯</name>
<gender>男</gender>
<age>36</age>
</student>
<student id="3">
<name>王五</name>
<gender>女</gender>
<age>24</age>
</student>
</class>
作为 Java 中最早支持的一种 XML 解析方式,可以不用依赖任何第三方包,通过 JDK 提供的 w3c 包里面的 api,即可实现快速解析,代码编程简单。
DOM 解析 XML 文档的时候,会在内存中加载整个文档来构造层次结构。
优点:
1.能快速遍历 XML 中任意节点数据,同时允许应用程序对数据和结构做出更改
2.可以在任何时候在树中上下导航,获取和操作任意部分的数据
缺点:
加载数据量比较小的 XML 文档问题不大,加载大的 XML 文档,内存消耗会很大,有内存溢出的风险
实现:
import org.w3c.dom.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.InputStream;
public class DomDemo {
public static void main(String[] args) {
// 1.获取xml文件流
InputStream inputStream = DomDemo.class.getClassLoader().getResourceAsStream("demo.xml");
// 2.创建DocumentBuilderFactory对象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 3.创建DocumentBuilder对象
try {
DocumentBuilder builder = factory.newDocumentBuilder();
Document d = builder.parse(inputStream);
NodeList stdList = d.getElementsByTagName("student");
for (int i = 0; i <stdList.getLength() ; i++) {
Node std = stdList.item(i);
// 遍历标签属性
NamedNodeMap attrs = std.getAttributes();
for(int j=0; j< attrs.getLength(); j++){
Node attr = attrs.item(j);
System.out.println(attr.getNodeName()+":"+attr.getNodeValue());
}
// 遍历标签子节点
NodeList childNodes = std.getChildNodes();
for (int k = 0; k <childNodes.getLength() ; k++) {
if (childNodes.item(k).getNodeType()== Node.ELEMENT_NODE) {
System.out.println(childNodes.item(k).getNodeName() + ":" + childNodes.item(k).getTextContent());
}
}
System.out.println("==============");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
结果:
id:1
name:张三
gender:男
age:26
==============
id:2
name:里斯
gender:男
age:36
==============
id:3
name:王五
gender:女
age:24
==============
是 JDK 提供的另一种 XML 解析方式,相比于 DOM,SAX 每次解析只在内存中加载 XML 文件的一小部分,即使针对较大的 XML 文件,它也不需要占用太多的内存,也不会存在内存溢出的问题。
优点:
1.采用事件驱动模式一段一段的来解析数据,占用内存小
2.只在读取数据时检查数据,不需要保存在内存中
3.效率和性能较高,能解析大于系统内存的文档
缺点:
1.与 DOM 解析器相比,使用 SAX 解析器读取 XML 文件时,解析逻辑比较复杂
2.同时无法定位文档层次,很难同时访问同一文档的不同部分数据,不支持 XPath
实现:
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
public class SAXDemo {
public static void main(String[] args) throws Exception {
// 1.获取xml文件流
InputStream inputStream = SAXDemo.class.getClassLoader().getResourceAsStream("demo.xml");
// 2.获取SAXParserFactory实例
SAXParserFactory factory = SAXParserFactory.newInstance();
// 3.获取SAXparser实例
SAXParser saxParser = factory.newSAXParser();
// 4.创建Handel对象
SAXDemoHandel handel = new SAXDemoHandel();
// 5.解析XML文件
saxParser.parse(inputStream, handel);
// 6.获取读取结果
List<Map<String, String>> students = handel.getStudents();
for (Map<String, String> student : students) {
System.out.println(student.toString());
}
}
}
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SAXDemoHandel extends DefaultHandler {
private String value;
private Map<String, String> student;
private List<Map<String, String>> students = new ArrayList<>();
public List<Map<String, String>> getStudents() {
return students;
}
/**
* xml 解析开始
* @throws SAXException
*/
@Override
public void startDocument() throws SAXException {
super.startDocument();
System.out.println("xml 解析开始");
}
/**
* xml 解析结束
* @throws SAXException
*/
@Override
public void endDocument() throws SAXException {
super.endDocument();
System.out.println("xml 解析结束");
}
/**
* 解析 XML 元素开始
* @param uri
* @param localName
* @param qName
* @param attributes
* @throws SAXException
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
System.out.println("开始遍历节点:" + qName);
if (qName.equals("student")){
student = new HashMap<>();
for(int i=0; i<attributes.getLength();i++){
student.put(attributes.getQName(i), attributes.getValue(i));
}
}
}
/**
* 解析 XML 元素结束
* @param uri
* @param localName
* @param qName
* @throws SAXException
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
System.out.println("节点遍历结束:" + qName);
if(qName.equals("student")){
students.add(student);
student = null;
} else if(qName.equals("name") || qName.equals("gender") || qName.equals("age")){
student.put(qName, value);
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
// 获取节点值数组
value = new String(ch,start,length).trim();
if (!value.equals("")) {
System.out.println(value);
}
}
}
结果:
{gender=男, name=张三, id=1}
{gender=男, name=里斯, id=2}
{gender=女, name=王五, id=3}
JDOM 是 Java 生态中非常优秀的 XML 解析库,相当于是 DOM 及 SAX 的结合版,同时在设计上弥补 DOM 及 SAX 在实际应用当中的不足之处。
优点:
1.基于树的模型处理 XML 文件,数据会加载在内存中
2.没有向下兼容的限制,因此比 DOM 简单
3.速度快,缺陷少
4.具有 SAX 的解析特征
5.API 比 DOM 更容易理解
缺点:
1.不能处理大于内存的 XML 文档
2.不支持与 DOM 中相应遍历包
实现:
<!--jdom -->
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1.3</version>
</dependency>
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import java.io.InputStream;
import java.util.List;
public class JdomDemo {
public static void main(String[] args) throws Exception {
// 1.获取xml文件流
InputStream inputStream = JdomDemo.class.getClassLoader().getResourceAsStream("demo.xml");
// 2.创建SAXBuilder对象
SAXBuilder saxBuilder = new SAXBuilder();
// 3.将输入流加载到build中
Document document = saxBuilder.build(inputStream);
// 4.获取根节点
Element rootElement = document.getRootElement();
// 5.获取子节点
List<Element> children = rootElement.getChildren();
for (Element child : children) {
List<Attribute> attributes = child.getAttributes();
// 遍历标签属性
for (Attribute attr : attributes) {
System.out.println(attr.getName()+":"+attr.getValue());
}
// 遍历标签子节点
List<Element> childrenList = child.getChildren();
for (Element o: childrenList) {
System.out.println(o.getName() + ":" + o.getValue());
}
System.out.println("==============");
}
}
}
结果:
id:1
name:张三
gender:男
age:26
==============
id:2
name:里斯
gender:男
age:36
==============
id:3
name:王五
gender:女
age:24
==============
DOM4J 是 JDOM 的升级产品。
优点:
1.性能优异,功能强大,极端易使用
2.开发简便,同时也提供了一些提高性能的代替方法
3.支持 XPath
缺点:
内存占用较大:dom4j将整个XML文档加载到内存中进行解析和操作
实现:
<!-- dom4j -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
public class Dom4jDemo {
public static void main(String[] args) throws Exception {
// 1.获取xml文件流
InputStream inputStream = Dom4jDemo.class.getClassLoader().getResourceAsStream("demo.xml");
// 2.创建Reader对象 进行流模式解析,减少内存的使用。
SAXReader reader = new SAXReader();
// 使用 SAXReader 的 setFeature 方法启用 DOM4J 的低内存占用模式。
// 3.加载xml
Document document = reader.read(inputStream);
// 4.获取根节点
Element rootElement = document.getRootElement();
// 5.遍历元素
Iterator iterator = rootElement.elementIterator();
while (iterator.hasNext()){
Element stu = (Element) iterator.next();
// 遍历标签属性
List<Attribute> attributes = stu.attributes();
for (Attribute attribute : attributes) {
System.out.println(attribute.getName() + ":" + attribute.getValue());
}
// 遍历标签子节点
Iterator iterator1 = stu.elementIterator();
while (iterator1.hasNext()){
Element stuChild = (Element) iterator1.next();
System.out.println(stuChild.getName()+":"+stuChild.getStringValue());
}
System.out.println("==============");
}
}
}
结果:
id:1
name:张三
gender:男
age:26
==============
id:2
name:里斯
gender:男
age:36
==============
id:3
name:王五
gender:女
age:24
==============
目前许多开源项目中大量采用 DOM4J,例如 Hibernate 框架中就用到 DOM4J 来读取 XML 配置文件,以及 Sun 的 JAXM 也在用 DOM4J。
对于需要使用 XML 解析工具,如果项目中没有什么包袱,首选 DOM4J。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。