SAX JSON解析

SAX解析XML

//xml内容
<?xml version="1.0" encoding="UTF-8"?>
<people>
    <person personid="E01">
        <name>Tony Blair</name>
        <address>10 Downing Street,London,UK</address>
        <tel>(061) 98765</tel>
        <fax>(061) 98765</fax>
        <email>blair@everywhere.com</email>
    </person>
    <person personid="E02">
        <name>Bill Clinton</name>
        <address>White House,USA</address>
        <tel>(010) 6400 98765</tel>
        <fax>(010) 6400 98765</fax>
        <email>bill@everywhere.com</email>
    </person>
</people>

//生成的类
package saxDemo;

public class Person {
    //XML解析的变量属性都是String
    private String personid;
    private String name;
    private String address;
    private String tel;
    private String fax;
    private String email;

    public String getPersonid() {
        return personid;
    }

    public void setPersonid(String personid) {
        this.personid = personid;
    }

    public String getName() {
        return name;
    }

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

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getTel() {
        return tel;
    }

    public void setTel(String tel) {
        this.tel = tel;
    }

    public String getFax() {
        return fax;
    }

    public void setFax(String fax) {
        this.fax = fax;
    }

    public String getEmail() {
        return email;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "personid='" + personid + '\'' +
                ", name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", tel='" + tel + '\'' +
                ", fax='" + fax + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}

//解析过程
package saxDemo;

import org.xml.sax.SAXException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class XMLDemo {
    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
        //解析步骤:

        //1. 创建一个SAX解析器工厂对象
        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
        //2. 通过工厂对象创建SAX解析器
        SAXParser saxParser = saxParserFactory.newSAXParser();
        //3. 创建一个数据处理器(由自己编写)
        PersonHandler personHandler = new PersonHandler();
        //4. 开始解析
        InputStream is = Thread.currentThread().getContextClassLoader().
                getResourceAsStream("saxDemo/person.xml");
        saxParser.parse(is,personHandler);
        List<Person> persons = personHandler.getPersons();
        for(Person p:persons){
            System.out.println(p);
        }

    }
}

//数据处理器
package saxDemo;

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

import java.util.ArrayList;
import java.util.List;

/**
 * 读取XML配置文件内容
 * SAX解析特点:
 * 1. 基于事件驱动
 * 2. 顺序读取,速度快
 * 3. 灵活性较差,不能任意读取节点
 * 4. SAX适用于在性能要求高的设备上使用
 */
public class PersonHandler extends DefaultHandler {

    private List<Person> persons = null;
    private Person p;//当前正在解析的person
    private String tag;//用于记录当前正在解析的标签名

    public List<Person> getPersons(){
        return persons;
    }

    //开始解析XML文档时调用
    @Override
    public void startDocument() throws SAXException {
        super.startDocument();
        persons = new ArrayList<>();
        System.out.println("开始解析文档");
    }

    //解析文档XML结束时调用
    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
        System.out.println("解析文档结束");
    }

    /**
     * 解析XML开始元素标签时调用
     * @param uri           命名空间
     * @param localName     不带前缀的标签名
     * @param qName         带前缀的标签名
     * @param attributes    当前标签的属性集合
     * @throws SAXException
     */
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        super.startElement(uri, localName, qName, attributes);
        if("person".equals(qName)){
            p = new Person();
            String personid = attributes.getValue("personid");
            p.setPersonid(personid);
        }
        tag = qName;
        System.out.println("startElemtype--"+qName);
    }

    //解析XML结束元素标签时调用
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        super.endElement(uri, localName, qName);
        if ("person".equals(qName)) {
            persons.add(p);
        }
        tag = null;//解析空格时直接跳过下面的多个判断,提高效率
        System.out.println("endElemtype--"+qName);
    }

    //解析标签内文本内容时调用
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        super.characters(ch, start, length);
        if(tag != null){
            if("name".equals(tag)){
                p.setName(new String(ch,start,length));
            }else if("address".equals(tag)){
                p.setAddress(new String(ch,start,length));
            }else if("tel".equals(tag)){
                p.setTel(new String(ch,start,length));
            }else if("fax".equals(tag)){
                p.setFax(new String(ch,start,length));
            }else if("email".equals(tag)){
                p.setEmail(new String(ch,start,length));
            }
        }
        System.out.println(ch);
    }
}

DOM解析XML

基于树型结构,通过解析器一次性把文档加载到内存,所以比较占内存,但更加灵活

//DOM解析
    public static void domParseXML() throws ParserConfigurationException, IOException, SAXException {
        //1. 创建一个DOM解析器工厂
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        //2. 通过工厂创建解析器对象
        DocumentBuilder documentBuilder = factory.newDocumentBuilder();
        //解析文档
        InputStream is = Thread.currentThread().
                getContextClassLoader().getResourceAsStream("saxDemo/person.xml");
        Document doc = documentBuilder.parse(is);//此代码完成后整个XML被以树状形式存储在内存中
        //从内存中读取数据
        NodeList personNodeList = doc.getElementsByTagName("person");//获取节点名称为person的所有结点
        ArrayList<Person> persons = new ArrayList<>();
        Person p = null;
        //此循环迭代两次
        for (int i = 0; i < personNodeList.getLength(); i++) {
            Node node = personNodeList.item(i);
            p = new Person();
            //获取结点的属性值
            String personid = node.getAttributes().getNamedItem("personid").getNodeValue();
            p.setPersonid(personid);
            //获取当前结点的所有子节点
            NodeList childNodes = node.getChildNodes();
            for (int j = 0; j < childNodes.getLength(); j++) {
                Node item = childNodes.item(j);
                String nodeName = item.getNodeName();
                if("name".equals(nodeName)){
                    //文本也是结点
                    p.setName(item.getFirstChild().getNodeValue());
                }else if("address".equals(nodeName)){
                    p.setAddress(item.getFirstChild().getNodeValue());
                }else if("tel".equals(nodeName)){
                    p.setTel(item.getFirstChild().getNodeValue());
                }else if("fax".equals(nodeName)){
                    p.setFax(item.getFirstChild().getNodeValue());
                }else if("email".equals(nodeName)){
                    p.setEmail(item.getFirstChild().getNodeValue());
                }
            }
            persons.add(p);
        }
        System.out.println("结果:");
        System.out.println(Arrays.toString(persons.toArray()));
    }

通过对象生成和读取XML文件

public void xmlEncoder() throws FileNotFoundException {
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("test.xml"));
    XMLEncoder xmlEncoder = new XMLEncoder(bos);
    Person p = new Person();
    p.setPersonid("1234");
    p.setAddress("广州");
    p.setEmail("qq.@com");
    p.setFax("ming");
    p.setTel("123456");
    p.setName("1224333");
    xmlEncoder.writeObject(p);
    xmlEncoder.close();
}

public static void xmlDecoder() throws FileNotFoundException {
    BufferedInputStream in = new BufferedInputStream(new FileInputStream("test.xml"));
    XMLDecoder decoder = new XMLDecoder(in);
    Person p = (Person)decoder.readObject();
    System.out.println(p);
}

JSON

  • 语法:
    {}:表示一个对象
    []:表示一个数组

  • 工具包:

  1. 阿里FastJson
    对于不需要序列化的字段,在类属性定义前加上:

    @JSONField(serialize=false)

对于空值,默认不显示,可以指定显示空字符串或null

SerializerFeature.WriteMapNullValue 显示null
SerializerFeature.WriteNullStringAsEmpty 显示空字符串
SerializerFeature.PrettyFormat 格式化输出
SerializerFeature.DisableCircularReferenceDetect 禁用循环引用检测

package com.xm.test;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xm.domain.Student;

import java.util.ArrayList;

public class JSONTest {
    public static void main(String[] args) {
        Student stu1 = new Student(123, null, 18);
        Student stu2 = new Student(321, "小张", 16);
        Student stu3 = new Student(666, "小邢", 8);

        /*用阿里FastJson*/
        //将java对象转换成字符串,第二个参数为是否美化
        String jsonString = JSON.toJSONString(stu1,true);
        System.out.println(jsonString);
        //创建集合
        ArrayList<Student> studentArrayList = new ArrayList<Student>();
        studentArrayList.add(stu1);
        studentArrayList.add(stu2);
        studentArrayList.add(stu3);
        String jsonString1 = JSON.toJSONString(
                studentArrayList,
                SerializerFeature.WriteNullStringAsEmpty,
                SerializerFeature.PrettyFormat
        );
        System.out.println(jsonString1);

        //将json转换成java对象
        String jsonString2 = "{id:119,name:\"小飞\",age:19}";
        Student student = JSON.parseObject(jsonString2, Student.class);
        System.out.println(student.toString());
    }
}
  1. Jackson
package com.xm.test;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xm.domain.Student;

import java.io.IOException;

public class JSONTest2 {
    public static void main(String[] args) {
        Student stu1 = new Student(123, null, 18);
        Student stu2 = new Student(321, "小张", 16);
        Student stu3 = new Student(666, "小邢", 8);
        //把对象封装成json
        ObjectMapper mapper = new ObjectMapper();
        String string;
        try {
            string = mapper.writeValueAsString(stu1);
            System.out.println(string);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        //把字符串转换成json
        String jsonString2 = "{\"id\":119,\"name\":\"小飞\",\"age\":19}";
        try {
            mapper.readValue(jsonString2,Student.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}