XML与JSON

XML

准备

  • junit依赖

    • junit
    • hamcrest-core
  • Person类

public class Person {
    private String personid;
    private String name;
    private String address;
    private String tel;
    private String fax;
    private String email;

    @Override
    public String toString() {
        return "Person{" +
                "personid='" + personid + '\'' +
                ", name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", tel='" + tel + '\'' +
                ", fax='" + fax + '\'' +
                ", email='" + 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;
    }
}
  • person.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>(001) 6400 98765</tel>
		<fax>(001) 6400 98765</fax>
		<email>bill@everywhere.com</email>
	</person>
</people>

SAX解析XML

自己编写一个数据处理器

public class PersonHandler extends DefaultHandler {

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

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


    //开始解析文档时调用
    @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("解析文档结束.");
    }

    /**
     * 解析开始元素(标签)时调用
     * @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("startElement--"+qName);
    }

    //解析结束元素时调用
    @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("endElement--"+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);
        }
    }
}
    /**
     * SAX解析的特点
     * 基于事件驱动
     * 顺序读取、速度快
     * 不能任意读取节点(灵活性差)
     * 解析时占用的内存小
     * SAX更适用于在性能要求更高的设备上使用(Android开发中)
     */
    @Test
    public void saxParseXML() 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("com/vince/xml/person.xml");
        saxParser.parse(is, personHandler);
        List<Person> persons = personHandler.getPersons();
        for (Person p : persons) {
            System.out.println(p);
        }
    }

DOM解析(Web开发)

  • 使用接口
    /**
     * DOM解析XML
     * 基于树型结构,通过解析器一次性把文档加载到内存中,所以会比较占用内存,可以随机访问
     * 更加灵活,更适合在web开发中使用
     */
    @Test
    public void domParseXML() throws ParserConfigurationException, IOException, SAXException {
        // 1、创建一个DOM解析器工厂对象
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        // 2、通过工厂对象创建解析器对象
        DocumentBuilder documentBuilder = factory.newDocumentBuilder();
        // 3、解析文档
        InputStream is = Thread.currentThread().getContextClassLoader()
                .getResourceAsStream("com/vince/xml/person.xml");

        //此代码完成后,整个XML文档已经被加载到内存中,以树状形式存储
        Document doc = documentBuilder.parse(is);

        // 4、从内存中读取数据

        //获取节点名称为person的所有节点,返回节点集合
        NodeList personNodeList = doc.getElementsByTagName("person");
        ArrayList<Person> persons = new ArrayList<>();
        Person p = null;

        //此循环会迭代两次
        for (int i = 0; i < personNodeList.getLength(); i++) {
            Node personNode = personNodeList.item(i);
            p = new Person();
            //获取节点的属性值
            String personid = personNode.getAttributes().getNamedItem("personid").getNodeValue();
            p.setPersonid(personid);
            //获取当前节点的所有子节点
            NodeList childNodes = personNode.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()));
    }

JDOM解析XML

  • 使用具体的类
  • 依赖
    • jdom
 /**
     * JDOM解析XML
     * 与DOM类似,基于树型结构
     * 与DOM的区别: 第三方组件库、实现JAVA的Collection接口、效率比DOM更高
     */
    @Test
    public void jdomParseXML() throws IOException, JDOMException {
        // 创建JDOM解析器
        SAXBuilder builder = new SAXBuilder();
        InputStream is = Thread.currentThread().getContextClassLoader()
                .getResourceAsStream("com/vince/xml/person.xml");
        org.jdom2.Document build = builder.build(is);
        Element rootElement = build.getRootElement();
        List<Person> list = new ArrayList<>();
        Person person = null;
        List<Element> children = rootElement.getChildren();
        for (Element element : children) {
            person = new Person();
            String personid = element.getAttributeValue("personid");
            person.setPersonid(personid);
            List<Element> childen1 = element.getChildren();
            for (Element e : childen1) {
                String tag = e.getName();
                if ("name".equals(tag)) {
                    person.setName(e.getText());
                } else if ("address".equals(tag)) {
                    person.setAddress(e.getText());
                } else if ("tel".equals(tag)) {
                    person.setTel(e.getText());
                } else if ("fax".equals(tag)) {
                    person.setFax(e.getText());
                } else if ("email".equals(tag)) {
                    person.setEmail(e.getText());
                }
            }
            list.add(person);
        }
        System.out.println("结果:");
        System.out.println(Arrays.toString(list.toArray()));
    }

DOM4J解析XML

依赖

  • dom4j
 /**
     * DOM4J解析XML
     * 基于树型结构,第三方组件库
     * 解析速度快、效率高,使用JAVA中的迭代器实现数据读取,在WEB框架中使用较多(Hibernate)
     */
    @Test
    public void dom4jParseXML() throws DocumentException {
        // 1、创建DOM4J的解析器对象
        SAXReader reader = new SAXReader();
        InputStream is = Thread.currentThread().getContextClassLoader()
                .getResourceAsStream("com/vince/xml/person.xml");
        org.dom4j.Document doc = reader.read(is);
        org.dom4j.Element rootElement = doc.getRootElement();
        Iterator<org.dom4j.Element> iterator = rootElement.elementIterator();
        ArrayList<Person> persons = new ArrayList<>();
        Person p = null;
        while (iterator.hasNext()) {
            p = new Person();
            org.dom4j.Element e = iterator.next();
            p.setPersonid(e.attributeValue("personid"));
            Iterator<org.dom4j.Element> iterator1 = e.elementIterator();
            while (iterator1.hasNext()) {
                org.dom4j.Element next = iterator1.next();
                String tag = next.getName();
                if ("name".equals(tag)) {
                    p.setName(next.getText());
                } else if ("address".equals(tag)) {
                    p.setAddress(next.getText());
                } else if ("tel".equals(tag)) {
                    p.setTel(next.getText());
                } else if ("fax".equals(tag)) {
                    p.setFax(next.getText());
                } else if ("email".equals(tag)) {
                    p.setEmail(next.getText());
                }
            }
            persons.add(p);
        }
        System.out.println("结果:");
        System.out.println(Arrays.toString(persons.toArray()));
    }

通过对象生成XML

 /**
     * 把对象写入XML
     */
    @Test
    public void xmlEncode() {
        try {
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("test.xml"));
            XMLEncoder xmlEncoder = new XMLEncoder(bos);
            Person p = new Person();
            p.setPersonid("1212@qq.com");
            p.setAddress("北京");
            p.setEmail("12324@qq.com");
            p.setFax("2716732472");
            p.setTel("12432545");
            p.setName("38");
            xmlEncoder.writeObject(p);
            xmlEncoder.close();

        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

从XML文件中读取对象

    /**
     * 从XML文件中读取对象
     */
    @Test
    public void xmlDecoder() {
        try {
            BufferedInputStream in = new BufferedInputStream(new FileInputStream("test.xml"));
            XMLDecoder decoder = new XMLDecoder(in);
            Person p = (Person) decoder.readObject();
            System.out.println(p);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

使用第三方xstream组件实现XML的解析与生成

依赖

  • xstream
  • xpp3
 @Test
    public void xStream(){
        Person p = new Person();
        p.setPersonid("1212");
        p.setPersonid("1212@qq.com");
        p.setAddress("北京");
        p.setEmail("12324@qq.com");
        p.setFax("2716732472");
        p.setTel("12432545");
        p.setName("38");

        XStream xStream = new XStream(new Xpp3Driver());
        xStream.alias("person",Person.class);
        xStream.useAttributeFor(Person.class,"personid");
        String xml = xStream.toXML(p);
        System.out.println(xml);

        //解析XML
        Person person = (Person) xStream.fromXML(xml);
        System.out.println(person);
    }

JSON

依赖

  • gson

解析一个JSON数组

  • names.json
[
  {"firstName":"Vince","lastName":"Ma","email":"1791705739@qq.com"},
  {"firstName":"Jason","lastName":"Hunter","email":"jason@google.com"}
]
  • Name类
public class Name {
    private String firstName;
    private String lastName;
    private String email;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

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

    public Name() {
    }

    public Name(String firstName, String lastName, String email) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
    }

    @Override
    public String toString() {
        return "Name{" +
                "firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}
    /**
     * 解析一个JSON数组
     */
    @Test
    public void parseJSONNames(){
        InputStream is = Thread.currentThread().getContextClassLoader()
                .getResourceAsStream("com/vince/json/names.json");
        InputStreamReader in = new InputStreamReader(is);
        //JSON的解析工具(解析器)
        JsonReader reader = new JsonReader(in);
        ArrayList<Name> list = new ArrayList<>();

        try {
            //开始解析数组
            reader.beginArray();
            while(reader.hasNext()){
                list.add(parseName(reader));
            }
            //结束解析数组
            reader.endArray();

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        System.out.println(Arrays.toString(list.toArray()));
    }


    //解析对象Name
    private Name parseName(JsonReader jsonReader){
        Name name = null;


        try {
            //开始解析对象
            jsonReader.beginObject();
            name = new Name();
            while(jsonReader.hasNext()){
                String attrName = jsonReader.nextName();
                if("firstName".equals(attrName)){
                    name.setFirstName(jsonReader.nextString());
                }else if("lastName".equals(attrName)){
                    name.setLastName(jsonReader.nextString());
                }else if("email".equals(attrName)){
                    name.setEmail(jsonReader.nextString());
                }
            }
            //结束解析对象
            jsonReader.endObject();

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return name;
    }

使用JsonReader解析复杂的JSON数据

  • message.json
[
  {
    "id": 912345678901,
    "text": "How do I read a JSON stream in Java?",
    "geo": null,
    "user": {
      "name": "json_newb",
      "followers_count": 41
    }
  },
  {
    "id": 912345678902,
    "text": "@json_newb just use JsonReader!",
    "geo": [50.454722, -104.606667],
    "user": {
      "name": "jesse",
      "followers_count": 2
    }
  }
]
  • User类
public class User {
    private String name;
    private int followers_count;

    public User() {
    }

    public User(String name, int followers_count) {
        this.name = name;
        this.followers_count = followers_count;
    }

    public String getName() {
        return name;
    }

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

    public int getFollowers_count() {
        return followers_count;
    }

    public void setFollowers_count(int followers_count) {
        this.followers_count = followers_count;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", followers_count=" + followers_count +
                '}';
    }
}

  • Message类
public class Message {
    private long id;
    private String text;
    private ArrayList<Double> geo;
    private User user;

    public Message() {
    }

    public Message(long id, String text, ArrayList<Double> geo, User user) {
        this.id = id;
        this.text = text;
        this.geo = geo;
        this.user = user;
    }

    public long getId() {
        return id;
    }

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

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public ArrayList<Double> getGeo() {
        return geo;
    }

    public void setGeo(ArrayList<Double> geo) {
        this.geo = geo;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public String toString() {
        return "Message{" +
                "id=" + id +
                ", text='" + text + '\'' +
                ", geo=" + geo +
                ", user=" + user +
                '}';
    }
}
  • 测试解析
    /**
     * 使用JsonReader解析复杂的JSON数据
     */
    @Test
    public void parseJSONMessage(){
        InputStream is = Thread.currentThread().getContextClassLoader()
                .getResourceAsStream("com/vince/json/message.json");
        InputStreamReader in = new InputStreamReader(is);
        JsonReader jsonReader = new JsonReader(in);
        ArrayList<Message> list = readMessageArray(jsonReader);
        for(Message m:list){
            System.out.println(m);
        }
    }

    //读取Message数组
    private ArrayList<Message> readMessageArray(JsonReader jsonReader){
        ArrayList<Message> list = new ArrayList<>();

        try {
            jsonReader.beginArray();
            while(jsonReader.hasNext()){
                list.add(readMessage(jsonReader));
            }
            jsonReader.endArray();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return list;
    }


    /**
     * 解析一个Message对象
     * @param jsonReader
     * @return
     */
    private Message readMessage(JsonReader jsonReader) {
        Message m = new Message();
        try {
            jsonReader.beginObject();
            while(jsonReader.hasNext()){
                String name = jsonReader.nextName();
                if("id".equals(name)){
                    m.setId(jsonReader.nextLong());
                }else if("text".equals(name)){
                    m.setText(jsonReader.nextString());
                }else if("geo".equals(name) && jsonReader.peek()!= JsonToken.NULL){
                    m.setGeo(readGeo(jsonReader));
                }else if("user".equals(name)){
                    m.setUser(readUser(jsonReader));
                }else{
                    jsonReader.skipValue();
                }
            }
            jsonReader.endObject();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return m;
    }


    /**
     * 解析User
     * @param jsonReader
     * @return
     */
    private User readUser(JsonReader jsonReader){
        User user = new User();

        try {
            jsonReader.beginObject();
            while(jsonReader.hasNext()){
                String name = jsonReader.nextName();
                if("name".equals(name)){
                    user.setName(jsonReader.nextString());
                }else if("followers_count".equals(name)){
                    user.setFollowers_count(jsonReader.nextInt());
                }else{
                    jsonReader.skipValue();
                }
            }
            jsonReader.endObject();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return user;
    }

    /**
     * 解析GEO
     */
    private ArrayList<Double> readGeo(JsonReader jsonReader){
        ArrayList<Double> list = new ArrayList<>();

        try {
            jsonReader.beginArray();
            while(jsonReader.hasNext()){
                list.add(jsonReader.nextDouble());
            }
            jsonReader.endArray();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return list;
    }

创建JSON

    @Test
    public void createJSON(){
        List<Name> list = new ArrayList<>();
        list.add(new Name("vince","ma","123435@qq.com"));
        list.add(new Name("April","Smily","12324@qq.com"));
        JsonArray array = new JsonArray();
        for(Name n:list){
            JsonObject obj = new JsonObject();
            obj.addProperty("firstName",n.getFirstName());
            obj.addProperty("lastName",n.getLastName());
            obj.addProperty("email",n.getEmail());
            array.add(obj);
        }
        System.out.println(array.toString());
    }

把一个JSON对象转换成JAVA对象,或把一个JAVA对象转换成JSON对象

  • name.json
{"firstName":"Vince","lastName":"Ma","email":"1791705739@qq.com"}
  • 测试
 @Test
    public void gson1(){
        Gson gson = new Gson();
        InputStream is = Thread.currentThread().getContextClassLoader()
                .getResourceAsStream("com/vince/json/name.json");
        InputStreamReader in = new InputStreamReader(is);
        Name name = gson.fromJson(in,Name.class);
        System.out.println(name);

        String json = gson.toJson(name);
        System.out.println(json);
    }

把一组JSON数组转换成一个JAVA对象集合,或者把一个JAVA对象集合转换成JSON对象

 @Test
    public void gson2(){
        Gson gson = new Gson();
        InputStream is = Thread.currentThread().getContextClassLoader()
                .getResourceAsStream("com/vince/json/names.json");
        InputStreamReader in = new InputStreamReader(is);
        TypeToken<List<Name>> typeToken = new TypeToken<List<Name>>(){};
        List<Name> list = gson.fromJson(in, typeToken.getType());
        System.out.println(list);


        String json = gson.toJson(list, typeToken.getType());
        System.out.println(json);
    }

    class MyTypeToken extends TypeToken<List<Name>>{}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值