一、简介
XML,一种可扩展标记语言,通常被开发人员用来传输和存储数据,定义也比较简单,通常如下方式开头,用来表述文档的一些信息。
<?xml version="1.0" encoding="UTF-8"?>
讯享网
例如下面这个简单的文档。
讯享网<?xml version="1.0" encoding="UTF-8"?> <site> <name>博客网站</name> <url>https://www.pzblog.cn</url> <desc>技术学习网站</desc> </site>
其中site、name、url、desc表示标签名称,内容表示标签对应的值。
因 XML 的平台无关性、语言无关性、系统无关性等特点,给系统之间的数据传输带来了极大的便利,广受开发者欢迎。
事实上,在 1996 年诞生之后,XML 逐渐成为了一种通用的数据交换格式。
不同的编程语言,解析 XML 的逻辑基本都是一样的,只不过实现的语法稍有不同。
今天我们就一起来学习一下,采用 Java 编程语言来解析 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>
二、DOM 解析
DOM 的全称是:Document Object Model,是 Java 中最早支持的一种 XML 解析方式,可以不用依赖任何第三方包,通过 JDK 提供的 w3c 包里面的 api,即可实现快速解析,代码编程简单。
DOM 解析 XML 文档的时候,会在内存中加载整个文档来构造层次结构,因此优势比较突出:
- 1.能快速遍历 XML 中任意节点数据,同时允许应用程序对数据和结构做出更改
- 2.可以在任何时候在树中上下导航,获取和操作任意部分的数据
当然也有缺点:
- 加载小的 XML 文档问题不大,加载大的 XML 文档,内存消耗会很大,有内存溢出的风险
总的来说,DOM 解析方式,对于数据量比较小的 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 ==============
三、SAX 解析
SAX 的全称是:Simple API for XML,也是 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 解析
JDOM 是 Java 生态中一个非常优秀的 XML 开源文档解析库,你可以把它看成是 DOM 及 SAX 的结合版,同时在设计上弥补了 DOM 及 SAX 在实际应用当中的不足之处。
优点如下:
- 1.基于树的模型处理 XML 文件,数据会加载在内存中
- 2.没有向下兼容的限制,因此比 DOM 简单
- 3.速度快,缺陷少
- 4.具有 SAX 的解析特征
- 5.API 比 DOM 更容易理解
当然也有缺点:
- 1.能处理大于内存的 XML 文档
- 2.不支持与 DOM 中相应遍历包
总体来讲,JDOM 对于大多数需要使用 XML 应用程序来说还是非常实用的。
实现过程如下:
<!--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 解析
DOM4J 也是 Java 生态中一款非常非常优秀的 XML 开源文档解析库,是 JDOM 的升级品。
最初,它是 JDOM 的一种分支,后来合并了许多超出基本 XML 文档表示的功能,最后单独作为一工具对外发布。
优点如下:
- 1.性能优异,功能强大,极端易使用
- 2.开发简便,同时也提供了一些提高性能的代替方法
- 3.支持 XPath
唯一的缺点:
- API 过于复杂
实现过程如下:
讯享网 <!-- 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(); // 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。
对于一些已经在项目中用到的 XML 解析工具,如果不考虑移植性问题,也可以改成 DOM4J 来实现,当然具体问题具体分析,如果迁移成本很高,以前的工具依然能正常运行,也没必要进行迁移。总之就是,适合的才是最好的,是否值得迁移,需要评估资源成本和时间以及必要性。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/19820.html