XML三种解析方式简介以及JAVA实现

1、DOM

  DOM解析XML文件时,会将XML文件的所有内容读取到内存中,然后允许您使用DOM API遍历XML树、检索所需的数据。使用DOM操作XML的代码看起来比较直观,并且,在某些方面比基于SAX的实现更加简单。但是,因为DOM需要将 XML文件的所有内容读取到内存中,所以内存的消耗比较大,特别对于运行Android的移动设备来说,因为设备的资源比较宝贵,所以建议还是采用SAX 来解析XML文件,当然,如果XML文件的内容比较小采用DOM是可行的。
  在解析之后每一个元素都会以Node的形式在内存中进行存储
  接下来使用代码进行演示
  XML文件内容

<?xml version="1.0" encoding="UTF-8" standalone="no"?><书架>
    <>
        <名称>平凡的世界</名称>
        <作者>路遥</作者>
        <售价>50</售价>
    </>

    <>
        <名称>人生哲思录</名称>
        <作者>周国平</作者>
        <售价>2000</售价>
    </>
</书架>

java代码内容

package XML_Study.DOM_Study;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
 * DocumentBuilderFactory->DocumentBuilder->Document->NsodeList之后就可以进行改变了
 * @author SHUXIN
 */
public class DOM {
    @Test
    public void DOMfind() throws Exception{//进行查找元素的值
        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = builderFactory.newDocumentBuilder();
        Document ducument = documentBuilder.parse("src/XML_Study/DOM_Study/DOM_Study.xml");
        NodeList nodeList = ducument.getElementsByTagName("售价");
        Node item1 = nodeList.item(1);
        String name=item1.getTextContent();
        System.out.println(name);
    }

    /**
     * 把整个文件加载到内存之中,之后通过树的结构进行操作
     * DocumentBuilderFactory->DocumentBuilder->Document->NsodeList之后就可以进行改变内存了
     * TransformerFactory->Transformer->newTransformer.transform(domsouce, outputTarget);//一个是Source一个接口,使用实现类DomSource,以及StreamResult
     * @throws Exception
     */
    @Test
    public void modifDOM() throws Exception {//改变指定元素的内容
        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = builderFactory.newDocumentBuilder();
        Document ducument = documentBuilder.parse("src/XML_Study/DOM_Study/DOM_Study.xml");
        NodeList nodeList = ducument.getElementsByTagName("售价");
        Node item1 = nodeList.item(1);
        item1.setTextContent("2000");

        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer newTransformer = transformerFactory.newTransformer();
        Source domsouce=new DOMSource(ducument);
        Result outputTarget=new StreamResult("src/XML_Study/DOM_Study/DOM_Study.xml");
        newTransformer.transform(domsouce, outputTarget);

    }
}

2.SAX

  SAX是一个解析速度快并且占用内存少的xml解析器,非常适合用于Android等移动设备。SAX解析XML文件采用的是事件驱动,也就是说,它并不需要解析完整个文档,在按内容顺序解析文档的过程中,SAX会判断当前读到的字符是否合法XML语法中的某部分,如果符合就会触发事件。所谓事件,其实就是一些回调(callback)方法,这些方法(事件)定义在ContentHandler接口。
 这种方式解析是一种基于事件驱动的api,有两个部分,解析器和事件处理器:
解析器就是XMLReader接口,负责读取XML文档,和向事件处理器发送事件(也是事件源),
事件处理器ContentHandler接口,负责对发送的事件响应和进行XML文档处理。对于SAX解析方式可以使用ContentHandle的实现类
以下是SAX的图解,建议之后通过代码对照理解
这里写图片描述
SAX常用事件如下:
startDocument() —-文档开始事件
startElement() —-元素开始事件
characters() —-文本元素事件
endElement() —-元素结束事件
endDocument() —-文档结束事件
这里写图片描述
XML文件同上

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<书架>
    <>
        <名称>平凡的世界</名称>
        <作者>路遥</作者>
        <售价>50</售价>
    </>

    <>
        <名称>人生哲思录</名称>
        <作者>周国平</作者>
        <售价>2000</售价>
    </>
</书架>

JAVA代码片,这边只是使用了
characters() —-文本元素事件
endElement() —-元素结束事件
endDocument() —-文档结束事件

package XML_Study.SAX_Study;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.junit.Test;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

public class SAX_study {
    /**
     * sax解析基础操作,大多数都是用handle来进行,重写defaultHandle类中的方法来进行,原因是使用ContentHandle重写的方法太多了
     * 其他的东西都可以进行一系列的操作来进行
     * @throws Exception
     */
    @Test
    public void SAXParserTest1() throws Exception{
        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
        SAXParser newSAXParser = saxParserFactory.newSAXParser();
        XMLReader reader=newSAXParser.getXMLReader();
        reader.setContentHandler(new DefaultHandler(){
            @Override
            public void startElement(String uri, String localName, String qName, Attributes attributes)//遇到开始元素所做的工作
                    throws SAXException {
                System.out.println("开始标签"+qName);
            }
            @Override
            public void endElement(String uri, String localName, String qName) throws SAXException {//遇到结束元素所做的工作
                System.out.println("结束标签"+qName);
            }
            @Override
            public void characters(char[] ch, int start, int length) throws SAXException {//遇到具体内容进行的操作
                System.out.println(new String(ch,start,length));
            }
        });
        reader.parse("src/XML_Study/SAX_Study/SAX_Study.xml");//开始解析
    }
}

3、PULL

  Pull解析器的运行方式与 SAX 解析器相似,都是轻量级的解析,在Android的内核中已经嵌入了Pull,所以我们不需要再添加第三方jar包来支持Pull。Android使用的就是pull进行解析所以pull显得尤为重要,但是pull和其他方式大同小异
  如果是编写java代码就需要导入第三方的jar包
  kxml2-2.3.0.jar和xmlpull_1_1_3_4c.jar版本没有太大的关系
Pull解析和Sax解析不一样的地方有:

  • pull读取xml文件后触发相应的事件调用方法返回的是数字
  • pull可以在程序中控制想解析到哪里就可以停止解析。

方便参照将XML再贴一次

<?xml version="1.0" encoding="UTF-8" standalone="no"?><书架>
    <>
        <名称>平凡的世界</名称>
        <作者>路遥</作者>
        <售价>50</售价>
    </>

    <>
        <名称>人生哲思录</名称>
        <作者>周国平</作者>
        <售价>2000</售价>
    </>
</书架>

在java代码中使用了一个Book类,里面只有Name,Author,Price三个变量以及对应的getter setter方法所以就不贴代码了

package XML_Study.Pull_Study;

import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import org.junit.Test;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
import com.sun.xml.internal.ws.api.pipe.NextAction;
import XML_Study.SAX_Study.Book;
public class PullParser_Study {
    public ArrayList<Book> booklist = new ArrayList();
    public boolean flag = false;
    public Book book = new Book();
/**
 * 使用了KXML 以及xmlpull包
 * @throws Exception
 */
    @Test
    public void Pull_Study() throws Exception {
        XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance();
        XmlPullParser newPullParser = xmlPullParserFactory.newPullParser();// 获取解析器
        newPullParser.setInput(new FileInputStream(new File("src/XML_Study/SAX_Study/SAX_Study.xml")), "UTF-8");// 第一个参数是输入流,第二个参数是编码格式
        int EvenType = newPullParser.getEventType();//使用一个常量进行保存,我们得到的元素的类型
        while (EvenType != XmlPullParser.END_DOCUMENT) {// 表示只要不是为文件的末尾就可以了
            switch (EvenType) {
            case XmlPullParser.START_TAG://开始的元素
                if (newPullParser.getName().equals("书")) {
                    book = new Book();
                }
                if (newPullParser.getName().equals("名称")) {
                    book.setName(newPullParser.nextText());//使用nextText()函数得到内容
                }
                if (newPullParser.getName().equals("作者")) {
                    book.setAuthor(newPullParser.nextText());
                }
                if (newPullParser.getName().equals("售价")) {
                    book.setPrice(newPullParser.nextText());
                }
            case XmlPullParser.END_TAG://表示结束的元素
                if (newPullParser.getName().equals("书架")) {
                for(Book book:booklist )
                    System.out.println(book.getName()+" "+book.getAuthor()+" "+book.getPrice());
                }if(newPullParser.getName().equals("书")){
                    booklist.add(book);
                }
            }
            EvenType=newPullParser.nextTag();//切忌加上此行代码,防止出现死循环
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值