SAX解析

Posted handsomecui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SAX解析相关的知识,希望对你有一定的参考价值。

1DOM解析与SAX解析比较:

DOM解析

SAX解析

原理: 一次性加载xml文档,不适合大容量的文件读取

原理: 加载一点,读取一点,处理一点。适合大容量文件的读取

DOM解析可以任意进行增删改成

SAX解析只能读取

DOM解析任意读取任何位置的数据,甚至往回读

SAX解析只能从上往下,按顺序读取,不能往回读

DOM解析面向对象的编程方法(NodeElementAttribute,Java开发者编码比较简单。

SAX解析基于事件的编程方法。java开发编码相对复杂。

2 SAX解析工具

SAX解析工具-  Sun公司提供的。内置在jdk中。org.xml.sax.*

 

核心的API

   SAXParser类: 用于读取和解析xml文件对象

parseFile f, DefaultHandler dh)方法: 解析xml文件

 

参数一: File:表示 读取的xml文件。

    参数二: DefaultHandlerSAX事件处理程序。使用DefaultHandler的子类

例如:{

      1.创建SAXParser对象  

              SAXParser parser=SAXParserFactory.newInstance().newSAXParser();

       2.调用parse方法

    parser.parse(new File("./src/contact.xml"), new MyDefaultHandler());

   }

 

  3.DefaultHandler类的API:

 

    void startDocument()  :  在读到文档开始时调用

 

    void endDocument()  :在读到文档结束时调用

 

    void startElement(String uri, String localName, String qName, Attributes attributes)  :读到开始标    签时调用

 

    void endElement(String uri, String localName, String qName)   :读到结束标签时调用

 

    void characters(char[] ch, int start, int length)   读到文本内容时调用

3.SAM解析练习:

  1.基本练习,查看函数调用;

  SamExercise.java:

package com.dom4j.SAM;

import java.io.File;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;

public class SamExercise {

    public static void main(String[] args) throws Exception, SAXException {
        SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
        parser.parse(new File("./src/contact.xml"), new MyDefalutHandler());
    }

}
View Code

 

  MyDefalutHandler.java:

package com.dom4j.SAM;

import javax.xml.stream.events.StartDocument;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class MyDefalutHandler extends DefaultHandler{
    @Override
    public void startDocument() throws SAXException {
        System.out.println("MyDefalutHandler.startDocument()");
    }
    
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        System.out.println("MyDefalutHandler.startElement()->>>" + qName);
    }
    
    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        System.out.println("MyDefalutHandler.characters()->>>" + new String(ch, start, length));
    }
    
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        System.out.println("MyDefalutHandler.endElement()->>>" + qName);
    }
    
    @Override
    public void endDocument() throws SAXException {
        System.out.println("MyDefalutHandler.endDocument()");
    }
}
View Code

  2.读取打印出来xml文件:

  contact.xml:

<?xml version="1.0" encoding="gb2312"?>
<contactList>
    <contact id="001">
        <name>张三</name>
        <age>20</age>
        <phone>134222223333</phone>
        <email>zhangsan@qq.com</email>
        <qq>432221111</qq>
    </contact>
    <contact id="003" value="hello">
        <name>lisi</name>
        <age>20</age>
        <phone>134222225555</phone>
        <email>lisi@qq.com</email>
        <qq>432222222</qq>
    </contact>
    <contact></contact>
</contactList>
View Code

  DisplayAllContent.java:

package com.dom4j.SAM;

import java.io.File;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;

public class DisplayAllContent {

    public static void main(String[] args) throws Exception, SAXException {
        SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
        MyDisplayAllContentHandle handle = new MyDisplayAllContentHandle();
        parser.parse(new File("./src/contact.xml"), handle);
        System.out.println(handle.getContent());
    }

}
View Code

  MyDisplayAllContentHandle:

package com.dom4j.SAM;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class MyDisplayAllContentHandle extends DefaultHandler {
    private static StringBuffer sb;
    static{
        sb = new StringBuffer();
    }
    public String getContent(){
        return sb.toString();
    }
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        sb.append("<");
        sb.append(qName);
        for(int i = 0; i < attributes.getLength(); i++){
            sb.append(" " + attributes.getQName(i));
            sb.append("=" + "\\"" + attributes.getValue(i) + "\\"");
        }
        sb.append(">");
    }
    
    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        sb.append(new String(ch, start, length));
    }
    
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        sb.append("</");
        sb.append(qName + ">");
    }
}
View Code

 

  3.将xml文件内容放在一个类中,并输出:

  contact.java:

package com.dom4j.SAM;

public class contact {
    private String id;
    private String name;
    private String age;
    private String qq;
    private String email;
    private String phone;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAge() {
        return age;
    }
    public void setAge(String age) {
        this.age = age;
    }
    public String getqq() {
        return qq;
    }
    public void setqq(String qq) {
        this.qq = qq;
    }
    public String getemail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    @Override
    public String toString() {
        return "Person \\n id=" + id + ", name=" + name + ", age=" + age + ", qq=" + qq
                + ", email=" + email + ", phone=" + phone + "\\n";
    }
    
}
View Code

  ReadValue.java:

package com.dom4j.SAM;

import java.io.File;
import java.util.ArrayList;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;


public class ReadValue{
    
    public static void main(String[] args) throws Exception, SAXException {
        SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
        MyReadValueHandle handle = new MyReadValueHandle();
        parser.parse(new File("./src/contact.xml"), handle);
        ArrayList<contact> list = handle.getList();
        for(contact acontact : list){
            System.out.println(acontact);
        }
    }
}
View Code

  MyReadValueHandle.java:

package com.dom4j.SAM;

import java.util.ArrayList;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;



public class MyReadValueHandle extends DefaultHandler {
    
    private ArrayList<contact> list = new ArrayList<contact>();
    private contact acontact;
    private String curTag;
    
    public ArrayList<contact> getList(){
        return list;
    }
    
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        curTag = qName;
        if(qName.equals("contact")){
            acontact = new contact();
            acontact.setId(attributes.getValue("id"));
        }
    }
    
    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        String content = new String(ch, start, length);
        if("name".equals(curTag)){
            acontact.setName(content);
        }
        if("age".equals(curTag)){
            acontact.setAge(content);
        }
        if("phone".equals(curTag)){
            acontact.setPhone(content);
        }
        if("email".equals(curTag)){
            acontact.setEmail(content);
        }
        if("qq".equals(curTag)){
            acontact.setqq(content);
        }
    }
    
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        curTag = null;//注意!!避免换行空格的影响
        if(qName.equals("contact")){
            list.add(acontact);
        }
    }
}
View Code

  4.设计一个通讯录程序

  联系人: 编号  姓名  性别  年龄  电话  QQ 邮箱

  功能要求:

    添加联系人

    修改联系人

    删除联系人

    查询所有联系人

  思路:添加联系人的时候先把输入的内容放在一个配置文件中config.txt,然后用BeanUtil框架从这个配置文件中读取内容用dom解析,放到contact.xml中,修改的时候直接用xpath技术得到id,通过dom解析修改xml中的内容,删除和修改类同,查询的时候直接用的SAX解析;

  代码:

main.java

package com.dom4j.contacts;

import java.util.Scanner;

public class Main {
    public static void main(String[] args) throws Exception {
        Scanner cin = new Scanner(System.in);
        String operate;
        while(true){
            System.out.println("================");
            System.out.println("【1】添加联系人");
            System.out.println("【2】修改联系人");
            System.out.println("【3】删除联系人");
            System.out.println("【4】查询所有联系人");
            System.out.println("【Q】退出程序");
            System.out.println("==================");
            operate = cin.nextLine();
            if(operate.equals("Q")){
                break;
            }
            if(operate.equals("1")){
                new AlterContact().addContact();
            }
            if(operate.equals("2")){
                new AlterContact().alterContact();
            }
            if(operate.equals("3")){
                new AlterContact().deleteContact();
            }
            if(operate.equals("4")){
                new QueryContact().display();
            }
            
        }
    }
}
View Code

contact.java:

package com.dom4j.contacts;

public class Contact {
    private String id, name, sex, phone, qq, email;
    private String age;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return id + "\\t" + name + "\\t" + age + "\\t" + sex
                + "\\t" + phone + "\\t" + qq + "\\t" + email;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getQq() {
        return qq;
    }

    public void setQq(String qq) {
        this.qq = qq;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
    
}
View Code

AlterContact.java:

package com.dom4j.contacts;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import java.util.Scanner;
import org.apache.commons.beanutils.BeanUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.ElementHandler;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.xml.sax.DocumentHandler;


import sun.font.CreatedFontTracker;


public class AlterContact {
    private Scanner cin = new Scanner(System.in);
    private static Contact contact;
    private Properties properties;
    
    static{
        contact = new Contact();
    }
    
    public void addContact() throws Exception {
        WriteFile();
        //读取配置文件
        properties = new Properties();
        Class clazz = AlterContact.class;
        InputStream inputStream = clazz.getResourceAsStream("/config.txt");
        //注意这个文件在bin目录下的,并不在src下,错了半天才发现!!!
        try {
            properties.load(inputStream);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //向配置文件中读取数据加入xml文件中
        Document doc = new SAXReader().read("./src/contact.xml");
        List nodes = doc.selectNodes("//contactList");
        Element list = (Element)nodes.get(0);
        Element newContact = list.addElement("contact");
        newContact.addAttribute("id", properties.getProperty("id"));
        newContact.addElement("age").setText(properties.getProperty("age"));
        newContact.addElement("name").setText(properties.getProperty("name"));
        newContact.addElement("sex").setText(properties.getProperty("sex"));
        newContact.addElement("phone").setText(properties.getProperty("phone"));
        newContact.addElement("qq").setText(properties.getProperty("qq"));
        newContact.addElement("email").setText(properties.getProperty("email"));
        //写入xml文件
        OutputFormat format = OutputFormat.createPrettyPrint();
        FileOutputStream outputStream = new FileOutputStream(new File("./src/contact.xml"));
        format.setEncoding("utf-8");
        XMLWriter writer = new XMLWriter(outputStream, format);
        writer.write(doc);
        writer.close();
        System.out.println("添加成功!");
    }

    public void alterContact() throws Exception {
        System.out.println("请输入您要修改的联系人的编号:");
        String id = cin.nextLine();
        Document doc = new SAXReader().read(new File("./src/contact.xml"));
        List list = doc.selectNodes("//contact[@id=" + id + "]");
        if(list.size() == 0){
            System.out.println("您要修改 的id不存在!");
            return;
        }
        Element acontact = (Element) list.get(0);
        System.out.println("您要修改的联系人信息为:");
        System.out.println("name: " + acontact.element("name").getText());
        System.out.println("sex: " + acontact.element("sex").getText());
        System.out.println("age: " + acontact.element("age").getText());
        System.out.println("phone: " + acontact.element("phone").getText());
        System.out.println("qq: " + acontact.element("qq").getText());
        System.out.println("email: " + acontact.element("email").getText());
        
        while(true){
            System.out.println("欢迎来到修改系统\\t如需退出请按Q键");
            System.out.println("请输入您要修改的项目:");
            String op = cin.nextLine();
            if(op.equals("Q")){
                return;
            }
            System.out.println("请输入修改的内容:");
            String va = cin.nextLine();
            acontact.element(op).setText(va);
            //写入xml文件
            OutputFormat format = OutputFormat.createPrettyPrint();
            FileOutputStream outputStream = new FileOutputStream(new File("./src/contact.xml"));
            format.setEncoding("utf-8");
            XMLWriter writer = new XMLWriter(outputStream, format);
            writer.write(doc);
            writer.close();
            System.out.println("修改成功!");
        }
        
    }

    public void deleteContact() throws Exception {
        System.out.println("请输入您要删除的联系人编号:");
        String id = cin.nextLine();
        Document doc = new SAXReader().read(new File("./src/contact.xml"));
        List<Element> list = (List<Element>)doc.selectNodes("//contact[@id=" + id + "]");
        if(list.size() == 0){
            System.out.println("您要删除的联系人不存在!");
            return;
        }
        for(Element contact : list){
            contact.detach();
        }
        //写入xml文件
        
        OutputFormat format = new OutputFormat().createPrettyPrint();
        FileOutputStream out = new FileOutputStream(new File("./src/contact.xml"));
        format.setEncoding("utf-8");
        XMLWriter writer = new XMLWriter(out, format);
        writer.write(doc);
        writer.close();
        System.out.println("删除成功! ");
    }
    
    private void WriteFile() throws Exception{
        BufferedWriter writer = new BufferedWriter(new FileWriter("./bin/config.txt"));
        //向配置文件中写数据放入对象中
        System.out.println("请输入编号:");
        String str = cin.nextLine();
        writer.write("id=" + str);
        BeanUtils.setProperty(contact, "id", str);
        writer.newLine();
        
        System.out.println("请输入姓名:");
        str = cin.nextLine();
        BeanUtils.setProperty(contact, "name", str);
        writer.write("name=" + str);
        writer.newLine();
        
        System.out.println("请输入性别:");
        str = cin.nextLine();
        BeanUtils.setProperty(contact, "sex", str);
        writer.write("sex=" + str);
        writer.newLine();
        
        System.out.println("请输入年龄:");
        str = cin.nextLine();
        BeanUtils.setProperty(contact, "age", str);
        writer.write("age=" + str);
        writer.newLine();
        
        System.out.println("请输入电话号码:");
        str = cin.nextLine();
        BeanUtils.setProperty(contact, "phone", str);
        writer.write("phone=" + str);
        writer.newLine();
        
        System.out.println("请输入qq:");
        str = cin.nextLine();
        BeanUtils.setProperty(contact, "qq", str);
        writer.write("qq=" + str);
        writer.newLine();
        
        System.out.println("请输入email:");
        str = cin.nextLine();
        BeanUtils.setProperty(contact, "email", str);
        writer.write("email=" + str);
        writer.newLine();
        writer.close();
    }

}
View Code

queryContact.java: