SAX和STAX解析xml文档

134 篇文章 1 订阅
55 篇文章 0 订阅
SAX 和 STAX 都是 基于事件驱动 ----- SAX推模式 STAX拉模式

SAX常用事件
startDocument() —- 文档开始事件
startElemen() —- 元素开始事件
characters() —- 文本元素事件
endElement() —- 元素结束事件
endDocument() —– 文档结束事件

为什么说SAX是推模式解析? 解析器控制xml文件解析,由解析器调用相应事件方法

在startElemen() endElement() 获得 开始和结束元素名称
在characters() 获得读取到文本内容
在startElemen() 读取属性值

案例如下:

public class Demo1 {
    public static void main(String[] args) throws Exception {
        // 1.建立工厂
        SAXParserFactory factory = SAXParserFactory.newInstance();
        // 2.创建handler
        SAXParser parser = factory.newSAXParser();
        // 3.创建handler
        Myhandler myhandler = new Myhandler();
        // 3.将xml文档和handler同时传递给解析器
        parser.parse(new File("sax.xml"), myhandler);
    }
}

class Myhandler extends DefaultHandler {
    @Override
    public void startDocument() throws SAXException {
        // TODO Auto-generated method stub
        super.startDocument();
        System.out.println("start documnet。。。。。");
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        // TODO Auto-generated method stub
        super.startElement(uri, localName, qName, attributes);
        System.out.println("start element。。。。" + qName);
        // 打印属性id
        if (qName.equals("server")) {
            System.out.println("id的属性值为" + attributes.getValue("id"));
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        // TODO Auto-generated method stub
        super.characters(ch, start, length);
        String content = new String(ch, start, length);
        System.out.println("character:" + content);
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        // TODO Auto-generated method stub
        super.endElement(uri, localName, qName);
        System.out.println("end Element...." + qName);
    }

    @Override
    public void endDocument() throws SAXException {
        // TODO Auto-generated method stub
        super.endDocument();
        System.out.println("end Document....");
    }
}

STAX拉模式解析xml—客户端程序,自己控制xmlshijian ,主动调用相应事件方法
当使用XML PULL 如果使用Android系统,系统内置无需下载任何开发包,如果想JavaSE JavaEE 使用pull 解析技术 下载单独pull 开发工具包xpp3 —– XML Pull Parser 3 是pull API 代码实现
使用pull 解析器
1、去网站上 下载 pull 解析器实现 xpp3 (Android 内置)
2、将 xpp3-1.1.3.4.C.jar 导入 java工程
导入jar包 位于 当前工程内部 , 在工程内新建 lib ,将jar复制过来 , 将pull 解析器 jar 添加build path

jar 包就是.class文件 集合压缩包 (采用zip格式压缩)

Pull解析器 使用 stax 解析方式 —- 拉模式解析
Pull采用将xml文档传递 解析器,手动通过next触发文档解析事件,在客户端代码中获取当前事件 ,从而调用相应事件处理方法

3、创建pull 解析器
4、将xml 文档内容传递 pull 解析器

为什么 STAX 解析方式 效率 好于 SAX ?
1、SAX 无选择性的,所有事件都会处理 解析方式,Stax 由用户控制需要处理事件类型
2、在使用Stax进行数据解析时,随时终止解析

Pull 解析器 生成 xml 文档功能 —- 通过 XmlSerializer 生成 xml 文档
解析xml : 文档开始、元素开始、文本元素、元素结束、文档结束
生成xml :生成文档声明(文档开始),元素开始、文本内容、元素结束 、文档结束
1、生成简单xml
2、通过对象数据生成xml
3、通过对象List数据生成xml

 1.首先下载xpp3-1.1.3.4.c.jar包 2.创建xml pull解析器 --XmlPullParse 3.将xml文档内容传递 解析器
     * 4。需要客户端程序手动完成解析 XmlPullParser存放解析方法。 next()
     * @Test
    public void demo() throws Exception {
        // 创建工厂
        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        // 2。将xml文件传递给解析器
        XmlPullParser parser = factory.newPullParser();
        // 3.将xml文件传递给解析器
        parser.setInput(new FileInputStream(new File("sax.xml")), "utf-8");
        // 4.获取当前事件类型
        /*
         * int event = parser.getEventType(); System.out.println(event);
         * parser.next(); int event2 = parser.getEventType();
         * System.out.println(event2);
         */
        int event = 0;
        while ((event = parser.getEventType()) != XmlPullParser.END_DOCUMENT) {
            // System.out.println(parser.getEventType());
            if (event == XmlPullParser.START_TAG) {
                // 所有数据从解析器获得
                System.out.println(parser.getName() + "元素开始了");
            }
            // 但因哪个元素结束了
            if (event == XmlPullParser.END_TAG) {
                System.out.println(parser.getName() + "元素结束了");
            }

            parser.next();
        }
    }

====================通过pull解析器技术查看编程高手秘籍的价格

@Test
    public void demo2() throws Exception {
        // 1.创建pull解析器
        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        // 2.创建builder对象
        XmlPullParser parser = factory.newPullParser();
        // 3.将xml文件传递给解析器
        parser.setInput(new FileInputStream("book.xml"), "utf-8");
        // 通过循环驱动事件解析
        int event1;
        boolean isfound = false;
        while ((event1 = parser.getEventType()) != XmlPullParser.END_DOCUMENT) {
            // 获取开始元素name
            if (event1 == XmlPullParser.START_TAG && parser.getName().equals("name")) {
                String nextText = parser.nextText();
                if (nextText.equals("java编程高手秘籍")) {
                    /*
                     * parser.next(); System.out.println("=====" + event1);
                     * parser.next(); String money = parser.nextText();
                     * System.out.println(money);
                     */
                    isfound = true;
                }
            }
            if (event1 == XmlPullParser.START_TAG && parser.getName().equals("price") && isfound) {
                System.out.println(parser.nextText());
                break;
            }
            parser.next();
        }
    }```

================================封装对象信息将对象写入到xml文件中

@Test
    public void demo2() throws Exception {
        Company company = new Company();
        company.setName("中国石油");
        company.setPnum(15);
        company.setCompanyaddr("科学大道立交");
        /**
         * <company> <name>中国石油</name> <price>200</price>
         * <address>科学大道立交</address> </company>
         */
        // 获得序列化对象
        XmlSerializer serializer = XmlPullParserFactory.newInstance().newSerializer();
        // 传递输出目标文件给序列化对象
        serializer.setOutput(new FileOutputStream("company.xml"), "utf-8");
        serializer.startDocument("utf-8", true);
        serializer.startTag(null, "company");
        serializer.startTag(null, "name");
        serializer.text(company.getName());
        serializer.endTag(null, "name");
        serializer.startTag(null, "pname");
        serializer.text(company.getPnum() + "");
        serializer.endTag(null, "pname");

        serializer.endTag(null, "company");
        serializer.endDocument();
    }

================================pull解析器生成xml文档功能

@Test
    public void demo1() throws Exception {
        // 1.获取XmlSerializer对象

        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        XmlSerializer serializable = factory.newSerializer();
        // 设置序列化输出文档
        serializable.setOutput(new FileOutputStream("company.xml"), "utf-8");// 设定保存的编码集
        /**
         * 生成文档功能 通过XmlSerializer生成xml文档
         * 
         */
        // 文档开始
        serializable.startDocument("utf-8", true);// 设为独立的
        // 元素开始
        serializable.startTag(null, "company");// 没有命名空间空间 “” 或者null
        // 文本元素
        serializable.text("平顶山学院");
        // 元素结束
        serializable.endTag(null, "company");

        // 文档结束
        serializable.endDocument();
        /**
         * <?xml version="1.0" encodin="utf=8" standalong="yes"?>
         * <compay>平顶山学院</company>
         */

    }

工具类对xml文档进行curd操作
主要包含两个方法1.从xml文档中获取内容到list集合中。
2.同时接收xml文件和List集合,将集合众数据写入xml文件

package com.stax.pull.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.*;

import javax.swing.text.html.HTMLEditorKit.Parser;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
import org.xmlpull.v1.XmlSerializer;

/**
 * 这样可以对xml文档进行curd操作 工具类 抽取两个方法,1.xml-----List 2.List----xml
 */
public class PullUtils {
    /**
     * 从xml文档中获取内容到list集合中。
     * 
     * @return
     */
    public static List<Company> parseXml3List(String filename) throws Exception {
        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        XmlPullParser parser = factory.newPullParser();
        parser.setInput(new FileInputStream(filename), "utf-8");
        List<Company> list = new ArrayList<Company>();
        Company company = null;
        int event;
        while ((event = parser.getEventType()) != parser.END_DOCUMENT) {
            if (event == parser.START_TAG && parser.getName().equals("company")) {
                company = new Company();
            }
            if ((event == parser.START_TAG && parser.getName().equals("name"))) {
                company.setName(parser.nextText());
            }
            if ((event == parser.START_TAG && parser.getName().equals("pname"))) {
                company.setPnum(Integer.valueOf(parser.nextText()));
            }
            if ((event == parser.START_TAG && parser.getName().equals("address"))) {
                company.setCompanyaddr(parser.nextText());
            }
            if (event == parser.END_TAG && parser.getName().equals("company")) {
                list.add(company);
            }
            parser.next();
        }
        return list;
    }

    /**
     * 同时接收xml文件和List集合,将集合众数据写入xml文件
     * 
     */
    public static void serializeList2Xml(List<Company> companies, String filename) throws Exception {
        // 获取序列化对象
        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        XmlSerializer serializer = factory.newSerializer();
        // 写入文件
        serializer.setOutput(new FileOutputStream(filename), "utf-8");
        // 文档开始
        serializer.startDocument("utf-8", true);
        // 根元素开始companies
        serializer.startTag(null, "companies");
        // 遍历集合List 每个List中Company对象生成一个片段
        for (Company company : companies) {
            System.out.println("=====" + company.toString());
            // company开始
            serializer.startTag(null, "company");
            // name属性开始
            serializer.startTag(null, "name");
            serializer.text(company.getName());
            // pnanme属性结束
            serializer.endTag(null, "name");
            // pname属性开始
            serializer.startTag(null, "pnames");
            serializer.text(String.valueOf(company.getPnum()));
            // pname属性结束
            serializer.endTag(null, "pnames");
            // address属性开始
            serializer.startTag(null, "address");
            serializer.text(company.getCompanyaddr());
            serializer.endTag(null, "address");
            serializer.endTag(null, "company");
        }
        serializer.endTag(null, "companies");
        serializer.endDocument();
    }

}

封装的company类

package com.stax.pull.test;

import org.omg.CORBA.INTERNAL;

public class Company {
    private String name;
    private int pnum;
    private String companyaddr;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getPnum() {
        return pnum;
    }
    public void setPnum(int pnum) {
        this.pnum = pnum;
    }
    public String getCompanyaddr() {
        return companyaddr;
    }
    public void setCompanyaddr(String companyaddr) {
        this.companyaddr = companyaddr;
    }
    @Override
    public String toString() {
        return "Company [name=" + name + ", pnum=" + pnum + ", companyaddr=" + companyaddr + "]";
    }

}

xml文档

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<companies>
    <company>
        <name>中国石油</name>
        <pname>15</pname>
        <address>科学大道立交</address>
    </company>
    <company>
        <name>CSDN</name>
        <pname>1000</pname>
        <address>西三旗</address>
    </company>
</companies>

对所写的工具类进行测试

@Test
    public void demo3() throws Exception {
        /**
         * 添加公司
         * 
         */
        List<Company> companies = PullUtils.parseXml3List("company.xml");

        Company company = new Company();
        company.setCompanyaddr("经开大道");
        company.setName("中燃国际");
        company.setPnum(1000);
        companies.add(company);
        PullUtils.serializeList2Xml(companies, "company_bak.xml");

    }

=============================


    @Test
    public void demo2() throws Exception {
        /*
         * 测试工具类PullCURD中方法
         *
         */
        // 将Comapny.xml文件复制给company_bak.xml;
        // 解析结合
        List<Company> listcompany = PullUtils.parseXml3List("company.xml");
        PullUtils.serializeList2Xml(listcompany, "company_bak.xml");
    }

    @Test
    public void demo() throws Exception {
        List<Company> companies = new ArrayList<Company>();
        Company company = null;
        // 将xml文件的数据封装成list集合
        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        XmlPullParser parser = factory.newPullParser();
        // 向解析器中传入xml文档
        parser.setInput(new FileInputStream("company.xml"), "utf-8");
        // 遍历解析
        int event;
        while ((event = parser.getEventType()) != XmlPullParser.END_DOCUMENT) {
            if (event == XmlPullParser.START_TAG && parser.getName().equals("company")) {
                company = new Company();
            }
            if (event == XmlPullParser.END_TAG && parser.getName().equals("company")) {
                companies.add(company);
            }
            if (event == XmlPullParser.START_TAG && parser.getName().equals("name")) {
                // name元素开始
                company.setName(parser.nextText());
            }
            if (event == XmlPullParser.START_TAG && parser.getName().equals("pname")) {
                company.setPnum(Integer.valueOf(parser.nextText()));
            }
            if (event == XmlPullParser.START_TAG && parser.getName().equals("address")) {
                company.setCompanyaddr(parser.nextText());
            }
            parser.next();
        }
        for (Company company2 : companies) {
            System.out.println(company2.toString());
        }
    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

uniquewdl

匆忙的人生,总有你喜欢的文章

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值