博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
XML四种解析(慕课笔记)
阅读量:2061 次
发布时间:2019-04-29

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

1.初次邂逅XML

表现:以“.xml”为文件扩展名的文件
储存:树状结构
冰与火之歌
乔治马丁
2014
89
安徒生
乔治马丁
2014
89
English
为什么要使用XML
思考1.不同应用程序之间的通信?
思考2.不同系统间的通信的通信?
思考3.不同平台间的通信的通信?

2.在java程序中如何获取xml文件的内容

解析方式:DOM SAX DOM4J JDOM

常见节点类型
节点类型 NodeType Named Constant nodeName的返回值 nodeValue的返回值
Element 1 ELEMENT_NODE element name null
Attr 2 ATTRIBUTE_NODE 属性名称 属性值
Text 3 TEXT_NODE text 节点内容
DOM方式 (将xml全部加载解析,再执行)
public void nodePrase() throws Exception{        //1.创建一个DocumentBuilderFactory的对象        DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();        //2.创建一个DocumentBuider的对象        DocumentBuilder db=dbf.newDocumentBuilder();        //3.DocumentBuilder .parse()解析xml文件 得到document对象        Document document=db.parse("books.xml");        //4.获取所有book节点        NodeList bookList = document.getElementsByTagName("book");        //5.遍历每一个book节点        for(int i=0;i
SAX解析 (边加载边解析)

1.通过SAXParserFactory的静态newInstance()方法获取SAXParserFactord的实例factory

2.通过SAXParserFactory实例获取SAXParser实例

3.创建SAXPraserHandler对象(需要重写 startDocument() endDocument() startElement() endElement()方法 )

4.解析xml文件

//如何保存book的节点信息呢

通过book的javabean对象来保存

//1.通过SAXParserFactory的静态newInstance()方法获取SAXParserFactord的实例factory        SAXParserFactory sf = SAXParserFactory.newInstance();        //2.通过SAXParserFactory实例获取SAXParser实例        SAXParser paser = sf.newSAXParser();        //3.创建SAXPraserHandler对象        SAXParserHandler ph = new SAXParserHandler();        //4.解析xml文件        paser.parse("books.xml", ph);        //5.获取ph中封装好的javabean对象        List list = ph.getList();        for (Object object : list) {            System.out.println(object);        }//SAXParserHandler类 (核心 )package com.heima.xml文件的解析;import java.util.ArrayList;import java.util.List;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;public class SAXParserHandler extends DefaultHandler{
private int bookIndex; private String value; private Book book; List list=new ArrayList(); /** * 用来遍历xml的开始标签 */ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { //调用DefaultHandler super.startElement(uri, localName, qName, attributes); //开始解析book元素标签 if(qName.equals("book")){ //创建book对象 book=new Book(); this.bookIndex++; System.out.println("===============开始遍历第"+bookIndex+"本书==============="); //已知Book属性的名称,根据属性名称获取属性值 /*String value = attributes.getValue("id"); System.out.println("book的节点"+value);*/ //不知道book元素下的属性的个数 int numm=attributes.getLength(); for(int i=0;i
getList() { return list; } public void setList(List
list) { this.list = list; }}
JDOM解析

0.导入jar包

//对 books.xml文件进行JDOM解析

1.创建一个SAXBuilder的对象

2.创建一个输入流,将xml文件加载到输入流中

3.通过document对象获取xml文件的根节点

4.获取根节点下的子节点的List集合

private Book bk;//book的实体    private List
list=new ArrayList
();//存放解析后 生成的book实体 @Test public void JDOMPrase() throws Exception{ //导入jar包 //对 books.xml文件进行JDOM解析 //1.创建一个SAXBuilder的对象 SAXBuilder saxBuilder=new SAXBuilder(); //2.创建一个输入流,将xml文件加载到输入流中 InputStream in=new FileInputStream("src/res/books.xml"); //解决乱码(用可以指定字符集的流进行包装) InputStreamReader isr = new InputStreamReader(in, "utf-8"); Document document = saxBuilder.build(isr); //3.通过document对象获取xml文件的根节点 Element rootElement = document.getRootElement(); //4.获取根节点下的子节点的List集合 List
booklist = rootElement.getChildren(); //继续进行解析 for (Element book : booklist) { System.out.println("-------------开始解析第"+(booklist.indexOf(book)+1)+"书-----------"); //解析book的属性 List
attributes = book.getAttributes(); //知道属性名 //String attributeValue = book.getAttributeValue("id"); //System.out.println(""); //针对不清楚book节点下属性的名字及数量 for (Attribute attr : attributes) { //创建book实体 bk =new Book(); //获取到属性名和属性值(都是有实际值的节点) String name = attr.getName(); String value = attr.getValue(); System.out.println("属性名:"+name+"~"+"属性值:"+value); //添加id if("id".equals(name)){ bk.setId(value); } } //对book节点的 子节点的节点名以及节点值的遍历 List
bookChilds = book.getChildren(); for (Element element : bookChilds) { String name = element.getName(); String value = element.getValue(); System.out.println("节点名:"+name+"~"+"节点值:"+value); //给book添加属性 if(name.endsWith("name")){ bk.setName(value); } else if(name.endsWith("author")){ bk.setAuthor(value); } else if(name.endsWith("year")){ bk.setYear(value); } else if(name.endsWith("price")){ bk.setPrice(value); } else if(name.endsWith("language")){ bk.setLanguage(value); } } list.add(bk); bk=null; System.out.println(list); System.out.println("-------------结束解析第"+(booklist.indexOf(book)+1)+"书-----------"); } }
DOM4j

​ 0.导入jar包

​ 1.创建SAXReader的对象reader

​ 2.通过reader对象的read方法加载books.xml文件,获取document对象

​ 3.通过document对象获取根节点

​ 4.通过element对象的elementIterator方法获取迭代器

​ 5.遍历迭代器,获取根节点中的信息

​ 6.获取book的属性值及属性名

​ 如果清楚xml文件的结构,也可以用xpath方法快速获取某个具体节点的属性。

private Book bk;//book的实体    private List
list=new ArrayList
();//存放解析后 生成的book实体 @Test public void DOM4jPrase() throws DocumentException{ //创建SAXReader的对象reader SAXReader reader=new SAXReader(); //通过reader对象的read方法加载books.xml文件,获取document对象 org.dom4j.Document document = reader.read(new File("src/res/books.xml")); //通过document对象获取根节点 org.dom4j.Element bookStore = document.getRootElement(); //通过element对象的elementIterator方法获取迭代器 Iterator elementIterator = bookStore.elementIterator(); //遍历迭代器,获取根节点中的信息 while(elementIterator.hasNext()){ bk=new Book(); System.out.println("====开始遍历某本书===="); org.dom4j.Element book=(org.dom4j.Element) elementIterator.next(); //获取book的属性值及属性名 List
attributes = book.attributes(); for (org.dom4j.Attribute attr : attributes) { String name = attr.getName(); String value = attr.getValue(); System.out.println("节点名:"+name+"~"+"节点值:"+value); if("id".equals(name)){ bk.setId(value); } } Iterator eit = book.elementIterator(); //遍历每一本书的节点 while(eit.hasNext()){ org.dom4j.Element bookChild = (org.dom4j.Element) eit.next(); String name = bookChild.getName(); String value = bookChild.getStringValue(); System.out.println("节点名:"+name+"~"+"节点值:"+value); if(name.endsWith("name")){ bk.setName(value); } else if(name.endsWith("author")){ bk.setAuthor(value); } else if(name.endsWith("year")){ bk.setYear(value); } else if(name.endsWith("price")){ bk.setPrice(value); } else if(name.endsWith("language")){ bk.setLanguage(value); } } list.add(bk); bk=null; System.out.println(list); System.out.println("===结束遍历某本书===="); } }

3.4种解析方式的比较

基础方法:DOM、SAX (DOM解析于平台无关的解析)(SAX基于事件驱动)

扩展方法:JDOM,DOM4J

DOM解析 是将xml文件 一次性加载到内存中

SAX解析 事件驱动 startDocument() endDocument() startElement() endElement()

DOM

优点 :

*形成了树结构,直观好理解,代码更易于修改

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

缺点:

*当xml文件很大时,内存消耗比较大容易影响解析性能并可能造成内存溢出

SAX

优点:

*采用事件驱动模式,堆内存耗费比较小

*适用于只需要处理xml中数据时

缺点:

*不易于编码

*很难同时访问同一个xml中的多处数据

JDOM

*仅仅使用具体类而不使用接口

*API大量使用了CollectionS类

*开放源码

DOM4J

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

*DOM4J使用接口和抽象基本类方法,是一个优秀的Java XML API

*具有性能优异,灵活性好,功能强大和易于使用的特点

*开放源码

四种解析速度分析

@Test    public void 性能测试() throws Exception{        long s1 = System.currentTimeMillis();        nodePrase();        long s12 = System.currentTimeMillis();        long s2 = System.currentTimeMillis();        SAXParse();        long s22 = System.currentTimeMillis();        long s3 = System.currentTimeMillis();        JDOMPrase();        long s32 = System.currentTimeMillis();        long s4 = System.currentTimeMillis();        DOM4jPrase();        long s42 = System.currentTimeMillis();        System.out.println("DOM"+(s12-s1));        System.out.println("SAX"+(s22-s2));        System.out.println("JDOM"+(s32-s3));        System.out.println("DOM4J"+(s42-s4));    }

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

你可能感兴趣的文章
国内外helm源记录
查看>>
牛客网题目1:最大数
查看>>
散落人间知识点记录one
查看>>
Leetcode C++ 随手刷 547.朋友圈
查看>>
手抄笔记:深入理解linux内核-1
查看>>
内存堆与栈
查看>>
Leetcode C++《每日一题》20200621 124.二叉树的最大路径和
查看>>
Leetcode C++《每日一题》20200622 面试题 16.18. 模式匹配
查看>>
Leetcode C++《每日一题》20200625 139. 单词拆分
查看>>
Leetcode C++《每日一题》20200626 338. 比特位计数
查看>>
Leetcode C++ 《拓扑排序-1》20200626 207.课程表
查看>>
Go语言学习Part1:包、变量和函数
查看>>
Go语言学习Part2:流程控制语句:for、if、else、switch 和 defer
查看>>
Go语言学习Part3:struct、slice和映射
查看>>
Go语言学习Part4-1:方法和接口
查看>>
Leetcode Go 《精选TOP面试题》20200628 69.x的平方根
查看>>
Leetcode C++ 剑指 Offer 09. 用两个栈实现队列
查看>>
Leetcode C++《每日一题》20200707 112. 路径总和
查看>>
云原生 第十一章 应用健康
查看>>
Leetcode C++ 《第202场周赛》
查看>>