博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java中xml的解析
阅读量:4190 次
发布时间:2019-05-26

本文共 11169 字,大约阅读时间需要 37 分钟。

XML是一种通用的数据交换格式,它的平台无关性、语言无关性、系统无关性、给数据集成与交互带来了极大的方便。XML在不同的语言环境中解析方式都是一样的,只不过实现的语法不同而已。

XML的解析方式分为四种:1、DOM解析;2、SAX解析;3、JDOM解析;4、DOM4J解析。其中前两种属于基础方法,是官方提供的平台无关的解析方式,其他语言也在使用的方法;后两种属于扩展方法,它们是在基础的方法上扩展出来的,只适用于java平台。

 

demo中使用的xml原文:

cxx1
Bob1
stars1
85
cxx2
Bob2
stars2
85
cxx3
Bob3
stars3
85

 

一、DOM解析

  DOM的全称是Document Object Model,也即文档对象模型。在应用程序中,基于DOM的XML分析器将一个XML文档转换成一个对象模型的集合(通常称DOM树),应用程序正是通过对这个对象模型的操作,来实现对XML文档数据的操作。通过DOM接口,应用程序可以在任何时候访问XML文档中的任何一部分数据,因此,这种利用DOM接口的机制也被称作随机访问机制。

  DOM接口提供了一种通过分层对象模型来访问XML文档信息的方式,这些分层对象模型依据XML的文档结构形成了一棵节点树。无论XML文档中所描述的是什么类型的信息,即便是制表数据、项目列表或一个文档,利用DOM所生成的模型都是节点树的形式。也就是说,DOM强制使用树模型来访问XML文档中的信息。由于XML本质上就是一种分层结构,所以这种描述方法是相当有效的。
  DOM树所提供的随机访问方式给应用程序的开发带来了很大的灵活性,它可以任意地控制整个XML文档中的内容。然而,由于DOM分析器把整个XML文档转化成DOM树放在了内存中,因此,当文档比较大或者结构比较复杂时,对内存的需求就比较高。而且,对于结构复杂的树的遍历也是一项耗时的操作。所以,DOM分析器对机器性能的要求比较高,实现效率不十分理想。不过,由于DOM分析器所采用的树结构的思想与XML文档的结构相吻合,同时鉴于随机访问所带来的方便,因此,DOM分析器还是有很广泛的使用价值的。

    优点:

      1、形成了树结构,有助于更好的理解、掌握,且代码容易编写。

      2、解析过程中,树结构保存在内存中,方便修改。

    缺点:

      1、由于文件是一次性读取,所以对内存的耗费比较大。

      2、如果XML文件比较大,容易影响解析性能且可能会造成内存溢出。

package com.xxx.org;import org.w3c.dom.*;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;/** * @Author: xxx * Dom操作xml * @Date: 2018/5/29 20:19 */public class MyDom {    //用Element方式    public static void element(NodeList list){        for (int i = 0; i 

 

运行结果:

二、SAX解析

  SAX的全称是Simple APIs for XML,也即XML简单应用程序接口。与DOM不同,SAX提供的访问模式是一种顺序模式,这是一种快速读写XML数据的方式。当使用SAX分析器对XML文档进行分析时,会触发一系列事件,并激活相应的事件处理函数,应用程序通过这些事件处理函数实现对XML文档的访问,因而SAX接口也被称作事件驱动接口。

    优点:

      1、采用事件驱动模式,对内存耗费比较小。

      2、适用于只处理XML文件中的数据时。

    缺点:

      1、编码比较麻烦。

      2、很难同时访问XML文件中的多处不同数据。

package jaxp_sax;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;import javax.xml.parsers.SAXParser;import javax.xml.parsers.SAXParserFactory;/** * @Author: xxx * SAX解析DOM * 一行一行  Handler * startElement * endElement * @Date: 2018/5/29 20:03 */public class mySax {    public static void main(String[] args) throws Exception {        //1.或去SAXParserFactory实例        SAXParserFactory factory = SAXParserFactory.newInstance();        //2.获取SAXparser实例        SAXParser saxParser = factory.newSAXParser();        //创建Handel对象        SAXDemoHandel handel = new SAXDemoHandel();        saxParser.parse("src/resources/demo.xml", handel);    }}class SAXDemoHandel extends DefaultHandler {    //遍历xml文件开始标签    @Override    public void startDocument() throws SAXException {        super.startDocument();        System.out.println("sax解析开始");    }    //遍历xml文件结束标签    @Override    public void endDocument() throws SAXException {        super.endDocument();        System.out.println("sax解析结束");    }    @Override    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {        super.startElement(uri, localName, qName, attributes);        if (qName.equals("student")){            System.out.println("============开始遍历student=============");            //System.out.println(attributes.getValue("rollno"));        }        else if (!qName.equals("student")&&!qName.equals("class")){            System.out.print("节点名称:"+qName+"----");        }    }    @Override    public void endElement(String uri, String localName, String qName) throws SAXException {        super.endElement(uri, localName, qName);        if (qName.equals("student")){            System.out.println(qName+"遍历结束");            System.out.println("============结束遍历student=============");        }    }    @Override    public void characters(char[] ch, int start, int length) throws SAXException {        super.characters(ch, start, length);        String value = new String(ch,start,length).trim();        if (!value.equals("")) {            System.out.println(value);        }    }}

 

运行结果:

三、JDOM解析

    特征:

      1、仅使用具体类,而不使用接口。

      2、API大量使用了Collections类。

 

org.jdom
jdom
1.1.3
package com.xxx.MyJDOM;import org.jdom.Attribute;import org.jdom.Document;import org.jdom.Element;import org.jdom.input.SAXBuilder;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.InputStream;import java.util.List;/** * @Author: xxx * JDom解析xml * 快速开发XML应用程序。 * 是一个开源项目 * JDOM主要用来弥补DOM和SAX在实际应用当中的不足。 * @Date: 2018/5/30 11:44 */public class test {    public static void main(String[] args) throws Exception {        //1.创建SAXBuilder对象        SAXBuilder saxBuilder = new SAXBuilder();        //2.创建输入流        InputStream is = new FileInputStream(new File("src/test/java/resources/demo.xml"));        //3.将输入流加载到build中        Document document = saxBuilder.build(is);        //4.获取根节点        Element rootElement = document.getRootElement();        //5.获取子节点        List
children = rootElement.getChildren(); for (Element child : children) { System.out.println("通过rollno获取属性值:"+child.getAttribute("rollno")); List
attributes = child.getAttributes(); //打印属性 for (Attribute attr : attributes) { System.out.println(attr.getName()+":"+attr.getValue()); } List
childrenList = child.getChildren(); System.out.println("======获取子节点-start======"); for (Element o : childrenList) { System.out.println("节点名:"+o.getName()+"---"+"节点值:"+o.getValue()); } System.out.println("======获取子节点-end======"); } }}

 

运行结果:

4、DOM4J解析

     特征:

      1、JDOM的一种智能分支,它合并了许多超出基本XML文档表示的功能。

      2、它使用接口和抽象基本类方法。

      3、具有性能优异、灵活性好、功能强大和极端易用的特点。

      4、是一个开放源码的文件

 

dom4j
dom4j
1.6.1

 

package com.xxx.DOM4J;import org.dom4j.Attribute;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;import java.io.File;import java.util.Iterator;import java.util.List;/** * @Author: xxx * Dom4j解析xml * @Date: 2018/5/30 12:21 */public class App {    public static void main(String[] args) throws Exception {        //1.创建Reader对象        SAXReader reader = new SAXReader();        //2.加载xml        Document document = reader.read(new File("src/main/java/resources/demo.xml"));        //3.获取根节点        Element rootElement = document.getRootElement();        Iterator iterator = rootElement.elementIterator();        while (iterator.hasNext()){            Element stu = (Element) iterator.next();            List
attributes = stu.attributes(); System.out.println("======获取属性值======"); for (Attribute attribute : attributes) { System.out.println(attribute.getValue()); } System.out.println("======遍历子节点======"); Iterator iterator1 = stu.elementIterator(); while (iterator1.hasNext()){ Element stuChild = (Element) iterator1.next(); System.out.println("节点名:"+stuChild.getName()+"---节点值:"+stuChild.getStringValue()); } } }}

 

运行结果:

 

Final:比较总结

  DOM4J性能最好,连Sun的JAXM也在用DOM4J。目前许多开源项目中大量采用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J来读取XML配置文件。如果不考虑可移植性,那就采用DOM4J。

      JDOM和DOM在性能测试时表现不佳,在测试10M文档时内存溢出。在小文档情况下还值得考虑使用DOM和JDOM。虽然JDOM的开发者已经说明他们期望在正式发行版前专注性能问题,但是从性能观点来看,它确实没有值得推荐之处。另外,DOM仍是一个非常好的选择。DOM实现广泛应用于多种编程语言。它还是许多其它与XML相关的标准的基础,因为它正式获得W3C推荐(与基于非标准的Java模型相对),所以在某些类型的项目中可能也需要它(如在JavaScript中使用DOM)。
      SAX表现较好,这要依赖于它特定的解析方式-事件驱动。一个SAX检测即将到来的XML流,但并没有载入到内存(当然当XML流被读入时,会有部分文档暂时隐藏在内存中)。

 

既然DOM4J是比较好的选择,那么就多整点关于他的操作demo,已被不时之需。

dom4j
dom4j
1.6.1
jaxen
jaxen
1.1-beta-6
package com.xxx.DOM4J_2;import java.io.File;import java.io.FileOutputStream;import java.util.List;import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.io.OutputFormat;import org.dom4j.io.SAXReader;import org.dom4j.io.XMLWriter;import org.junit.Test;public class Demo3 { 	@Test	public void method1() throws Exception {		// 创建解析器		SAXReader reader = new SAXReader();//这个是用来读取文件内容的		Document doc = reader.read(new File("students.xml")); //指定要读取的文件		//System.out.println(doc.asXML()); //打印出文件	}		//实现对XML文件的复制	@Test	public void method2() throws Exception {		// 得到Document		SAXReader reader = new SAXReader();		Document doc = reader.read(new File("students.xml"));				// 保存Document,指定将写入的目的文件(复制功能)		XMLWriter writer = new XMLWriter(new FileOutputStream("students_copy.xml"));		writer.write(doc); //开始写入	}		//遍历Document	@Test	public void method3() throws Exception {		// 要遍历文档,首先要得到Document对象		SAXReader reader = new SAXReader();		Document doc = reader.read(new File("students.xml")); 		//获取根元素		Element root = doc.getRootElement();		//获取根元素中所有student元素		List
stuEleList = root.elements("student"); // 循环遍历所有学生元素 for(Element stuEle : stuEleList) { //获取学生元素的number String number = stuEle.attributeValue("number"); //获取学生元素名为name的子元素的文本内容 String name = stuEle.elementText("name"); //获取学生元素名为age的子元素的文本内容 String age = stuEle.elementText("age"); //获取学生元素名为sex的子元素的文本内容 String sex = stuEle.elementText("sex"); System.out.println(number + ", " + name + ", " + age + ", " + sex); } } //添加元素 @Test public void method4() throws Exception { // 得到Document SAXReader reader = new SAXReader(); Document doc = reader.read(new File("src/students.xml")); //获取root元素 Element root = doc.getRootElement(); Element stuEle = root.addElement("student"); //添加了student元素 // 给stuEle添加属性,名为number,值为1003 stuEle.addAttribute("number", "1003"); // 分别为stuEle添加名为name、age、sex的子元素,并为子元素设置文本内容 stuEle.addElement("name").setText("wangWu"); stuEle.addElement("age").setText("18"); stuEle.addElement("sex").setText("male"); // 设置保存的格式化器 1. \t,使用什么来完成缩进 2. true, 是否要添加换行 OutputFormat format = new OutputFormat("\t", true); format.setTrimText(true); //去掉空白 // 在创建Writer时,指定格式化器 XMLWriter writer = new XMLWriter(new FileOutputStream("src/students_copy.xml"), format); writer.write(doc); } //修改元素 @Test public void method5() throws Exception { // 得到Document SAXReader reader = new SAXReader(); Document doc = reader.read(new File("src/students_copy.xml")); //使用XPath找到符合条件的元素 // 查询student元素,条件是number属性的值为1003 Element stuEle = (Element) doc.selectSingleNode("//student[@number='ITCAST_1003']"); //修改stuEle的age子元素内容为81 stuEle.element("age").setText("81"); //修改stuEle的sex子元素的内容为female stuEle.element("sex").setText("female"); } //删除元素 @Test public void method6() throws Exception { // 得到Document SAXReader reader = new SAXReader(); Document doc = reader.read(new File("src/students_copy.xml")); // 查找student元素,条件是name子元素的文本内容为wangWu Element stuEle = (Element) doc.selectSingleNode("//student[name='wangWu']"); // 2. 获取父元素,使用父元素删除指定子元素 stuEle.getParent().remove(stuEle); }}

 

 

转载地址:http://xgooi.baihongyu.com/

你可能感兴趣的文章
iPhone质量成迷?被吴彦祖一箭射穿,却还能开机
查看>>
2020魔幻“商战”:抢公章、发黄图、半夜翻工厂...最烂的小说都不敢这么写
查看>>
拼多多股价创新高 市值突破2000亿美元
查看>>
拼多多市值超2100亿美元 黄峥成中国第二大富豪
查看>>
小米11 Pro外观配置曝光:四摄加持、2K 120Hz四曲面屏
查看>>
《消费者报告》杂志:Model 3和Model S被评选为美国最佳豪华汽车
查看>>
官宣预热iQOO 7强悍配置:“性能铁三角”加持 给你强悍全感
查看>>
淘宝年度十大冷门职业公布:螺蛳粉闻臭师、丝袜调色师等入选
查看>>
滚蛋吧,2020的糟心事儿!2021,先“拼”为敬!
查看>>
改文案、删微博又道歉 广汽蔚来自导自演“比特币购车”乌龙案
查看>>
电动汽车冬季悲歌:我不是在充电,就是在充电的路上
查看>>
饿了么2020外卖备注图鉴:12个关键词覆盖我们的生活
查看>>
特斯拉2020全年交付49.955万辆车,未能完成50万辆目标
查看>>
比亚迪汽车发布品牌全新标识 取消了椭圆型边界
查看>>
2020年朋友圈十大谣言:包括蚊蝇可以传播新冠病毒等
查看>>
特斯拉陶琳:全新Model 3标准续航升级版新增前排双层玻璃、电尾等功能
查看>>
华为nova 8 Pro王者荣耀定制版曝光:内置小鲁班定制主题 电池盖镭雕小鲁班
查看>>
“在雪地拍张半裸照,才是滑雪的最大乐趣”
查看>>
上一次山西临汾的公共厕所,恨不得直接住进去
查看>>
卢伟冰:这几天黑稿明显增多了 法务又要忙了
查看>>