Java 操作 xml 文件之 SAX 解析 Java 操作 xml 文件之 SAX 解析

Java 操作 xml 文件之 SAX 解析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Alias_fa/article/details/82055172
  1. dom4j 解析:文档对象模型解析,是W3C指定的一套规范标准。需要把整个文档读取到内存中,占用内存大,解析慢,但是访问效率高,增删改查快。适合解析小型文档。
  2. SAX 解析:基于事件驱动解析文档,边读边解析,不必解析整个文档,解析速度快,但是访问效率低,只能从开始顺序解析。

2、SAX 解析

SAX 解析是基于事件驱动的,先介绍以下五个方法:

(1) void startDocument(); 解析文档开始时执行
(2) void endDocument(); 解析文档结束时执行
(3) void startElement(String uri, String localName, String qName,Attributes attributes); 遇到元素开始节点时执行
(4) void characters(char[] ch, int start, int length); 两尖括号之间时执行
(5) void endElement(String uri, String localName, String qName); 遇到元素结束节点时执行

这里写图片描述

输出到控制台
import java.io.IOException;

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

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

public class SAXParserHandler extends DefaultHandler {
    int comIndex = 0;

    // 用来标识解析开始
    @Override
    public void startDocument() throws SAXException {
        super.startDocument();
        System.out.println("SAX解析开始");
    }

    // 用来标识解析结束
    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
        System.out.println("SAX解析结束");
    }

    // 解析xml元素,每到开始标签都会调用下面这个方法
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        // 调用defaultHandler类的startElement方法
        super.startElement(uri, localName, qName, attributes);
        if (!qName.equals("city")&&!qName.equals("company")&&!qName.equals("person")) {
            System.out.print("节点名是:" + qName);
        }
        if (qName.equals("company")) {
            comIndex++; 
            System.out.println("开始遍历第" + comIndex + "个公司资料");
            System.out.println("节点名是:" + qName);
        }

        // 开始解析company元素的属性(已知company元素下的属性名称,根据名称获取属性值)
        if (qName.equals("company")) {
            String value = attributes.getValue("unitId");
            System.out.println("company的unitId属性值是" + value);
            String value2 = attributes.getValue("unitCode");
            System.out.println("company的unitCode属性值是" + value2);
            String value3 = attributes.getValue("unitName");
            System.out.println("company的unitName属性值是" + value3);
        }
/*
        // 不知道元素节点中属性的名称及个数,如何获取属性名和属性值
          int num = attributes.getLength();// 返回book元素下属性的个数 
          for (int i = 0; i < num; i++) { 
           System.out.print("company元素的第" + (i + 1) + "个属性名是:" + attributes.getQName(i)); 
           System.out.println("---属性值是:" + attributes.getValue(i));
         }
*/       
    }

    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        super.endElement(uri, localName, qName);
        // 判断是否对某一元素节点已经遍历结束
        if (qName.equals("company")) {
            System.out.println("结束遍历第" + comIndex + "个公司的资料");
            System.out.println();
        }
    }

    @Override
    // char[] ch代表相邻两个尖括号<>之间的内容
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        super.characters(ch, start, length);
        String value = new String(ch, start, length);
        if (!value.trim().equals("")) {
            System.out.println("=="+value);
        }
    }

    public static void main(String[] args) {
        String pathname = "E://temptest//xmlTest.xml";
        // 获取SAXParserFactory实例
        SAXParserFactory factory=SAXParserFactory .newInstance();
        //获取SAXParse的实例
        try {
            SAXParser parser=factory.newSAXParser();
            //创建SAXParserHandler对象
            SAXParserHandler handler=new SAXParserHandler();

            parser.parse(pathname, handler);
            } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}
     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
封装成对象
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

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

public class SAXReadXml extends DefaultHandler {
    private List<Map<String,String>> conList= new ArrayList<Map<String,String>>();
    private HashMap<String, String> map;// 用来封装 company 对象ֵ
    private String elementName;// 节点名称

    public void reader(String pathfile) {
        InputStream inStream = null;
        try {
            inStream = new FileInputStream(pathfile);
            SAXParserFactory saxfac = SAXParserFactory.newInstance();
            SAXParser saxParser = saxfac.newSAXParser();
            saxParser.parse(inStream, this);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                inStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    StringBuffer text = new StringBuffer("");

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        elementName = qName;
        if (qName.equals("company")||qName.equals("person")) {
            map = new HashMap<String, String>();
        }
    }

    @Override
    public void characters(char[] ch, int start, int length)throws SAXException {
        if (map != null && elementName != null) {
            String content = new String(ch, start, length);
            if (content.trim().length() > 0) {
                text.append(new String(ch, start, length));
                map.put(elementName, text.toString());
            }
            //如果是用某个对象的set方法赋值,则先判断节点名称
        //  if(elementName.equals("userName")) {
        //      user.setName(text.toString()); //假设给user对象的name赋值
        //  }
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName)throws SAXException {
    //  if (qName.equals("company")||qName.equals("person")){ //把 company 和 person 的对象添加到 list
    //      conList.add(map);
    //  }
        if (qName.equals("company")) {//只把 company 的对象添加到 list 
            conList.add(map);
        }
        elementName = null;
        text = new StringBuffer("");
    }

    //用来返回封装好的对象列表
    public  List<Map<String,String>> getCompanyList(){
        return conList;
    }

    public static void main(String[] args) {
        SAXReadXml xml = new SAXReadXml();
        xml.reader("E:\\temptest\\xmlTest.xml");
        List<Map<String,String>> list = xml.getCompanyList();
        for(Map<String,String> com:list){
            System.out.println(com);
        }
    }
}
     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98

不管我们要哪类还是哪个元素节点的内容,只要在 startElement 方法、characters 方法、endElement 方法中加入相应的判断、逻辑,就能解析到我们想要的内容,所以,尽管 SAX 解析比较麻烦,但是更灵活。




版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Alias_fa/article/details/82055172
  1. dom4j 解析:文档对象模型解析,是W3C指定的一套规范标准。需要把整个文档读取到内存中,占用内存大,解析慢,但是访问效率高,增删改查快。适合解析小型文档。
  2. SAX 解析:基于事件驱动解析文档,边读边解析,不必解析整个文档,解析速度快,但是访问效率低,只能从开始顺序解析。

2、SAX 解析

SAX 解析是基于事件驱动的,先介绍以下五个方法:

(1) void startDocument(); 解析文档开始时执行
(2) void endDocument(); 解析文档结束时执行
(3) void startElement(String uri, String localName, String qName,Attributes attributes); 遇到元素开始节点时执行
(4) void characters(char[] ch, int start, int length); 两尖括号之间时执行
(5) void endElement(String uri, String localName, String qName); 遇到元素结束节点时执行

这里写图片描述

输出到控制台
import java.io.IOException;

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

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

public class SAXParserHandler extends DefaultHandler {
    int comIndex = 0;

    // 用来标识解析开始
    @Override
    public void startDocument() throws SAXException {
        super.startDocument();
        System.out.println("SAX解析开始");
    }

    // 用来标识解析结束
    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
        System.out.println("SAX解析结束");
    }

    // 解析xml元素,每到开始标签都会调用下面这个方法
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        // 调用defaultHandler类的startElement方法
        super.startElement(uri, localName, qName, attributes);
        if (!qName.equals("city")&&!qName.equals("company")&&!qName.equals("person")) {
            System.out.print("节点名是:" + qName);
        }
        if (qName.equals("company")) {
            comIndex++; 
            System.out.println("开始遍历第" + comIndex + "个公司资料");
            System.out.println("节点名是:" + qName);
        }

        // 开始解析company元素的属性(已知company元素下的属性名称,根据名称获取属性值)
        if (qName.equals("company")) {
            String value = attributes.getValue("unitId");
            System.out.println("company的unitId属性值是" + value);
            String value2 = attributes.getValue("unitCode");
            System.out.println("company的unitCode属性值是" + value2);
            String value3 = attributes.getValue("unitName");
            System.out.println("company的unitName属性值是" + value3);
        }
/*
        // 不知道元素节点中属性的名称及个数,如何获取属性名和属性值
          int num = attributes.getLength();// 返回book元素下属性的个数 
          for (int i = 0; i < num; i++) { 
           System.out.print("company元素的第" + (i + 1) + "个属性名是:" + attributes.getQName(i)); 
           System.out.println("---属性值是:" + attributes.getValue(i));
         }
*/       
    }

    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        super.endElement(uri, localName, qName);
        // 判断是否对某一元素节点已经遍历结束
        if (qName.equals("company")) {
            System.out.println("结束遍历第" + comIndex + "个公司的资料");
            System.out.println();
        }
    }

    @Override
    // char[] ch代表相邻两个尖括号<>之间的内容
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        super.characters(ch, start, length);
        String value = new String(ch, start, length);
        if (!value.trim().equals("")) {
            System.out.println("=="+value);
        }
    }

    public static void main(String[] args) {
        String pathname = "E://temptest//xmlTest.xml";
        // 获取SAXParserFactory实例
        SAXParserFactory factory=SAXParserFactory .newInstance();
        //获取SAXParse的实例
        try {
            SAXParser parser=factory.newSAXParser();
            //创建SAXParserHandler对象
            SAXParserHandler handler=new SAXParserHandler();

            parser.parse(pathname, handler);
            } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
封装成对象
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

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

public class SAXReadXml extends DefaultHandler {
    private List<Map<String,String>> conList= new ArrayList<Map<String,String>>();
    private HashMap<String, String> map;// 用来封装 company 对象ֵ
    private String elementName;// 节点名称

    public void reader(String pathfile) {
        InputStream inStream = null;
        try {
            inStream = new FileInputStream(pathfile);
            SAXParserFactory saxfac = SAXParserFactory.newInstance();
            SAXParser saxParser = saxfac.newSAXParser();
            saxParser.parse(inStream, this);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                inStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    StringBuffer text = new StringBuffer("");

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        elementName = qName;
        if (qName.equals("company")||qName.equals("person")) {
            map = new HashMap<String, String>();
        }
    }

    @Override
    public void characters(char[] ch, int start, int length)throws SAXException {
        if (map != null && elementName != null) {
            String content = new String(ch, start, length);
            if (content.trim().length() > 0) {
                text.append(new String(ch, start, length));
                map.put(elementName, text.toString());
            }
            //如果是用某个对象的set方法赋值,则先判断节点名称
        //  if(elementName.equals("userName")) {
        //      user.setName(text.toString()); //假设给user对象的name赋值
        //  }
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName)throws SAXException {
    //  if (qName.equals("company")||qName.equals("person")){ //把 company 和 person 的对象添加到 list
    //      conList.add(map);
    //  }
        if (qName.equals("company")) {//只把 company 的对象添加到 list 
            conList.add(map);
        }
        elementName = null;
        text = new StringBuffer("");
    }

    //用来返回封装好的对象列表
    public  List<Map<String,String>> getCompanyList(){
        return conList;
    }

    public static void main(String[] args) {
        SAXReadXml xml = new SAXReadXml();
        xml.reader("E:\\temptest\\xmlTest.xml");
        List<Map<String,String>> list = xml.getCompanyList();
        for(Map<String,String> com:list){
            System.out.println(com);
        }
    }
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98

不管我们要哪类还是哪个元素节点的内容,只要在 startElement 方法、characters 方法、endElement 方法中加入相应的判断、逻辑,就能解析到我们想要的内容,所以,尽管 SAX 解析比较麻烦,但是更灵活。



猜你喜欢

转载自blog.csdn.net/qq_20448485/article/details/82082892