其他分享
首页 > 其他分享> > XML三大解析详解!!!(Dom、Sax、Pull)

XML三大解析详解!!!(Dom、Sax、Pull)

作者:互联网

文章目录


前言

文章内容:本文主要讲述XML的三大解析,


一、XML三大解析

Dom解析:百度百科上给的官方概念是Dom是一种解析器,Dom解析器把XML转换为JavaScript可存取的对象。以我的理解就是Dom解析是将XML文件全部载入内存,变成一棵Dom树,然后再通过获取这棵树的节点和节点列表来对XML文档进行解析。
Sax解析

Pull解析

二、XML三大解析优缺点

1.Dom解析优缺点

优点:
<1>Dom树是被加载入内存的,更加方便操作;
<2>Dom解析是支持读、写、重新排列等多种功能的;
缺点:
<1>需要将整个文件加载入内存,浪费时间和空间;
<2>如果文件过大的话还会导致内存溢出等问题;

2.Sax解析优缺点

优点:
<1>是一个元素一个元素的解析,对内存的耗费小;
缺点:
<1>编码麻烦;
<2>它的第一个优点也可以理解为它的缺点

3.Pull解析优缺点

优点:
<1>也是一个一个元素进行解析,但是同时解决了Dom和Sax解析的问题

三、案例分析

1.XML文档(store.xml)

<?xml version="1.0" encoding="utf-8"?>
<商场>
	<商品>
		<商品名>空调</商品名>
		<品牌>美的</品牌>
		<类型>家电</类型>
		<售价>2988.00元</售价>
	</商品>
	<商品>
		<商品名>豆浆机</商品名>
		<品牌>美的</品牌>
		<类型>988.00元</类型>
		<售价>家电</售价>
	</商品>
	<商品>
		<商品名>手机</商品名>
		<品牌>华为</品牌>
		<类型>2688元</类型>
		<售价>电子产品</售价>
	</商品>
	<商品>
		<商品名>水乳</商品名>
		<品牌>雅诗兰黛</品牌>
		<类型>2088.00元</类型>
		<售价>护肤品</售价>
	</商品>
</商场>

<>编程思路
①通过DocumentBuilderFactory工厂类获取DocumentBuilderFactory对象。这里采用DocumentFactory中的newInstance方法。
在这里插入图片描述

  //获取DocumentBuilderFactory一个实例
        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();

②通过DocumentBuilder类获取DocumentBuilder的一个实例,这里通过调用builderFactory中的newDocumentBuilder的方法
在这里插入图片描述

2.Dom解析案例

 //获取DocumentBuilder的一个实例
        DocumentBuilder documentBuilder = builderFactory.newDocumentBuilder();

③通过DocumentBuilder解析XML文档并获取Document对象(

 //通过documentBuilder 解析xml文档获得Document对象
        Document document=documentBuilder.parse("store.xml");

④通过元素的名称找到元素的集合,并将指定的所有元素输出

  NodeList nodeList=document.getElementsByTagName("商品名");
//        NodeList nodeList1=document.getElementsByTagName("售价");
        for(int i=0;i<nodeList.getLength();i++){
            Node node=nodeList.item(i);
            String content=node.getTextContent();
            System.out.println(content);
        }

⑤Dom有一个优点就是可以进行xml文档的修改,因为Dom树是被写入内存中,所以还需要用到I/O流来进行读取

源代码:

public class domTest {
    @Test
    public void domParse() throws Exception {
        //获取DocumentBuilderFactory一个实例
        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        //获取DocumentBuilder的一个实例
        DocumentBuilder documentBuilder = builderFactory.newDocumentBuilder();
        //通过documentBuilder 解析xml文档获得Document对象
        Document document = documentBuilder.parse("store.xml");
        //通过元素的名字可以找到元素的集合
        NodeList nodeList = document.getElementsByTagName("商品名");
//        NodeList nodeList1=document.getElementsByTagName("售价");
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node node = nodeList.item(i);
            String content = node.getTextContent();
            System.out.println(content);
        }
    }

    @Test
    public void changeXML() throws Exception {
        DocumentBuilderFactory documentBuilderFactory1 = DocumentBuilderFactory.newInstance();
        DocumentBuilder documnetBuilder1 = documentBuilderFactory1.newDocumentBuilder();
        Document document1 = documnetBuilder1.parse("store.xml");
        NodeList nodeList1 = document1.getElementsByTagName("商品名");
        //获取节点列表的第一个元素
        Node node = nodeList1.item(0);
        node.setTextContent("烤箱");
        TransformerFactory factory = TransformerFactory.newInstance();
        Transformer transformer = factory.newTransformer();
        Source source = new DOMSource(document1);
        Result result = new StreamResult("store.xml");
        transformer.transform(source, result);
        for (int i = 0; i < nodeList1.getLength(); i++) {
            Node node1 = nodeList1.item(i);
            String content = node1.getTextContent();
            System.out.println(content);
        }
    }

}

3.Sax解析案例

Sax和Dom的思想是一致的,代码也是类似书写,有区别的就是在获取工厂之后,Sax是通过获取reader,然后通过reader来设置ContentHandler,然后再对xml文档进行解析

源代码:
①一个一个元素进行解析

public class SaxTest {
    @Test
    public void saxParser() throws Exception {
        //获取工厂
        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
        SAXParser saxParser = saxParserFactory.newSAXParser();
        //获取xmlReader通过这个reader可以设置ContentHandler
        XMLReader xmlReader = saxParser.getXMLReader();
        xmlReader.setContentHandler(new myHandler());
        //对xml文档进行解析
        xmlReader.parse("store.xml");
    }

    //因为ContentHandler接口未实现的方法过多,所以继承ContentHandler的实现类DefaultHandler
    private class myHandler extends DefaultHandler {
        @Override
        public void startDocument() throws SAXException {
            super.startDocument();
            System.out.println("文档开始");
        }

        @Override
        public void endDocument() throws SAXException {
            super.endDocument();
            System.out.println("文档结束");
        }

        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            super.startElement(uri, localName, qName, attributes);
            System.out.println("开始标签<" + qName + ">");
        }

        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            super.endElement(uri, localName, qName);
            System.out.println("结束标签</" + qName + ">");
        }

        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            super.characters(ch, start, length);
            String text = new String(ch, start, length);
            System.out.println("文本内容" + text);
        }
    }
}

②对解析到的元素的某项内容进行修改

public class SaxTest1  {
    @Test
    public void saxParser() throws Exception {
        //获取工厂
        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
        //获取SAXParser对象
        SAXParser saxParser = saxParserFactory.newSAXParser();
        //获取reader
        XMLReader xmlReader = saxParser.getXMLReader();
        //为reader设置ContentHandler
        xmlReader.setContentHandler(new DefaultHandler(){
            //判断解析的一个元素是否完成
            boolean isType = false;
            //计数器用来传入你想解析的元素索引值
            int count = 0;

            @Override
            public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
                super.startElement(uri, localName, qName, attributes);
                //开始解析元素时遇到了类型,需要将isType置为true
                if ("类型".equals(qName)) {
                    isType = true;
                    //解析元素个数加1
                    count++;
                }
            }

            @Override
            public void endElement(String uri, String localName, String qName) throws SAXException {
                super.endElement(uri, localName, qName);
                //解析元素结束时,需要将isType置为false,防止解析下一个元素时,会因为isType的值而停止解析,这样我们设置isPrice的意义就不存在了
                if ("类型".equals(qName)) {
                    isType = false;
                }
            }

            @Override
            public void characters(char[] ch, int start, int length) throws SAXException {
                super.characters(ch, start, length);
                //当前解析的元素结束,输出元素的对应内容
                if (isType && count == 2)
                    System.out.println(new String(ch, start, length));
            }
        });
        //因为是读取一个元素,所以只需要覆盖重写DefaultHandler中的元素开始、结束、和元素的函数
        //解析xml文档
        xmlReader.parse("store.xml");

    }
}

③将xml文档解析成ArrayList集合

public class Store {
    private String goodsName;
    private String brandName;
    private String goodsType;

    @Override
    public String toString() {
        return "Store{" +
                "goodsName='" + goodsName + '\'' +
                ", brandName='" + brandName + '\'' +
                ", goodsType='" + goodsType + '\'' +
                ", goodsPrice='" + goodsPrice + '\'' +
                '}';
    }

    private String goodsPrice;

    public String getGoodsName() {
        return goodsName;
    }

    public void setGoodsName(String goodsName) {
        this.goodsName = goodsName;
    }

    public String getBrandName() {
        return brandName;
    }

    public void setBrandName(String brandName) {
        this.brandName = brandName;
    }

    public String getGoodsType() {
        return goodsType;
    }

    public void setGoodsType(String goodsType) {
        this.goodsType = goodsType;
    }

    public String getGoodsPrice() {
        return goodsPrice;
    }

    public void setGoodsPrice(String goodsPrice) {
        this.goodsPrice = goodsPrice;
    }
}

public class SaxTest2 {
    @Test
    public void saxParser() throws Exception {
        //获取工厂
        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
        //获取SAXParser实例
        SAXParser saxParser = saxParserFactory.newSAXParser();
        //获取reader
        XMLReader xmlReader = saxParser.getXMLReader();
        //设置ContentHandler
        xmlReader.setContentHandler(new DefaultHandler() {

            //创建一个集合用来存放元素对象
            ArrayList<Store> list = null;
            //创建商品对象
            Store store = null;
            String tag = null;

            //因为是解析成为ArrayList,是通过一个个元素加入集合而成,所以只需要覆盖重写三个函数
            @Override
            public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
                super.startElement(uri, localName, qName, attributes);
                //解析到商场的时候,创建商场集合
                if ("商场".equals(qName)) {
                    list = new ArrayList<Store>();
                } else if ("商品".equals(qName)) {//解析到商品的时候创建一个商品对象
                    store = new Store();
                }
                //解析到商品名的时候将商品名赋值给tag
                if ("商品名".equals(qName)) {
                    tag = "商品名";
                } else if ("品牌".equals(qName)) {//解析到商品品牌的时候将商品品牌赋值给tag
                    tag = "品牌";
                } else if ("售价".equals(qName)) {//解析到商品售价的时候将售价赋值给tag
                    tag = "售价";
                } else if ("类型".equals(qName)) {//解析到商品类型的时候将类型复制给tag
                    tag = "类型";
                }
            }

            @Override
            public void endElement(String uri, String localName, String qName) throws SAXException {
                super.endElement(uri, localName, qName);
                //将tag复原为null
                tag = null;
                //解析到商场集合结束的时候,将商场集合遍历输出
                if ("商场".equals(qName)) {
                    for (Store store1 : list) {
                        System.out.println(store1);
                    }
                } else if ("商品".equals(qName)) {//解析到商品集合结束的时候,将商品添加进入商场集合
                    list.add(store);
                }

            }

            @Override
            public void characters(char[] ch, int start, int length) throws SAXException {
                super.characters(ch, start, length);
                //解析到商品名的时候,将tag赋值给商品名
                if ("商品名".equals(tag)) {
                    store.setGoodsName(new String(ch, start, length));
                } else if ("品牌".equals(tag)) {//解析到商品品牌的时候,将tag赋值给品牌
                    store.setBrandName(new String(ch, start, length));
                } else if ("售价".equals(tag)) {//解析到商品售价的时候,将tag赋值给售价
                    store.setGoodsPrice(new String(ch, start, length));
                } else if ("类型".equals(tag)) {//解析到商品类型的时候,将tag赋值给类型
                    store.setGoodsType(new String(ch, start, length));
                }
            }
        });
        xmlReader.parse("store.xml");
    }
}

4.Pull解析案例

源代码:

持续更新中!!!

标签:XML,Pull,String,Dom,void,qName,tag,解析,public
来源: https://blog.csdn.net/qq_45842760/article/details/112528921