Java操作XML(3)--StAX方式处理XML

StAX(Stream API for XML)是一种针对XML的流式拉分析API。本文主要介绍使用StAX方式处理XML,文中所使用到的软件版本:Java 1.8.0_191。

1、StAX简介

       StAX通过提供一种基于事件迭代器(Iterator)的API让使用者去控制xml文档解析过程,遍历这个事件迭代器去处理每一个解析事件,解析事件可以看做是程序拉出来的,也就是程序促使解析器产生一个解析事件然后处理该事件,之后又促使解析器产生下一个解析事件,如此循环直到碰到文档结束符。

1.1、与SAX区别

SAX和STAX都是基于事件驱动的。
SAX是推模式----解析器控制xml文件解析,由解析器调用相应的事件方法。
STAX是拉模式-----客户端程序自己控制xml事件,主动调用相应的事件方法。

1.2、拉模式的优点

1.在拉模式中,事件是由分析应用程序生成的,因此把分析规则提供到客户端而不是分析器。
2.拉模式的代码更简单并且它比推模式使用更少的库。
3.拉模式客户端能同时读多个XML文档。
4.拉模式允许你过滤XML文档并且跳过分析事件。

2、StAX使用

2.1、XML文件

<?xml version="1.0" encoding="utf-8" ?>
<school:grade xmlns:school="http://www.w3.org/TR/html4/school/">
    <school:student rollno="1" school:age="10">
        <school:firstname>cxx1</school:firstname>
        <lastname>Bob1</lastname>
        <nickname>stars1</nickname>
        <marks>85</marks>
    </school:student>
    <student rollno="2">
        <firstname>cxx2</firstname>
        <lastname>Bob2</lastname>
        <nickname>stars2</nickname>
        <marks>85</marks>
    </student>
    <student rollno="3">
        <firstname>cxx3</firstname>
        <lastname>Bob3</lastname>
        <nickname>stars3</nickname>
        <marks>85</marks>
    </student>
</school:grade>

2.2、Java代码例子

该例子演示如何使用StAX方式解析XML以及使用StAX方式来生成XML。

package com.abc.demo.general.xml;

import org.apache.commons.lang.StringUtils;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.namespace.QName;
import javax.xml.stream.*;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.XMLEvent;
import java.util.ArrayList;
import java.util.List;

public class StaxCase {
    private static Logger logger = LoggerFactory.getLogger(StaxCase.class);

    /**
     * 基于光标的方式解析xml
     * @throws Exception
     */
    @Test
    public void parse() throws Exception {
        XMLInputFactory factory = XMLInputFactory.newInstance();
        XMLStreamReader reader = factory.createXMLStreamReader(StaxCase.class.getResourceAsStream("student.xml"));
        //添加过滤器
        XMLStreamReader filterReader = factory.createFilteredReader(reader, new StreamFilter() {
            @Override
            public boolean accept(XMLStreamReader reader) {
                //处理开始节点
                if (reader.isStartElement() || reader.isEndElement() || reader.isCharacters()) {
                    return true;
                }
                return false;
            }
        });

        List<Student> students = new ArrayList<>();
        Student student = null;
        String text = "";
        while (filterReader.hasNext()) {
            int type = filterReader.next();
            if (type == XMLStreamReader.START_ELEMENT) {
                if ("student".equals(reader.getName().getLocalPart())) {
                    student = new Student();
                    students.add(student);

                    student.setRollno(Integer.parseInt(reader.getAttributeValue("", "rollno")));
                    String age = reader.getAttributeValue("http://www.w3.org/TR/html4/school/", "age");
                    if (StringUtils.isNotBlank(age)) {
                        student.setAge(Integer.parseInt(age));
                    }
                }
            } else if (type == XMLStreamReader.END_ELEMENT) {
                logger.info(reader.getName().getLocalPart());
                if ("firstname".equals(reader.getName().getLocalPart())) {
                    student.setFirstname(text);
                } else if ("lastname".equals(reader.getName().getLocalPart())) {
                    student.setLastname(text);
                } else if ("nickname".equals(reader.getName().getLocalPart())) {
                    student.setNickname(text);
                } else if ("marks".equals(reader.getName().getLocalPart())) {
                    student.setMarks(text);
                }

            } else if (type == XMLStreamReader.CHARACTERS) {
                text = reader.getText();
            }
        }
        logger.info(students.toString());
    }

    /**
     * 基于迭代模型的方式解析xml
     * @throws Exception
     */
    @Test
    public void parse2() throws Exception {
        XMLInputFactory factory = XMLInputFactory.newInstance();
        XMLEventReader reader = factory.createXMLEventReader(StaxCase.class.getResourceAsStream("student.xml"));
        //添加过滤器
        XMLEventReader filterReader = factory.createFilteredReader(reader, event -> {
            //处理开始节点
            if (event.isStartElement() || event.isEndElement() || event.isCharacters()) {
                return true;
            }
            return false;
        });

        List<Student> students = new ArrayList<>();
        Student student = null;
        String text = "";
        while (filterReader.hasNext()) {
            XMLEvent event = filterReader.nextEvent();
            if (event.isStartElement()) {
                if ("student".equals(event.asStartElement().getName().getLocalPart())) {
                    student = new Student();
                    students.add(student);

                    student.setRollno(Integer.parseInt(event.asStartElement().getAttributeByName(new QName("", "rollno")).getValue()));
                    Attribute ageAttribute = event.asStartElement().getAttributeByName(new QName("http://www.w3.org/TR/html4/school/", "age"));
                    if (ageAttribute != null) {
                        student.setAge(Integer.parseInt(ageAttribute.getValue()));
                    }
                }
            } else if (event.isEndElement()) {
                logger.info(event.asEndElement().getName().getLocalPart());
                if ("firstname".equals(event.asEndElement().getName().getLocalPart())) {
                    student.setFirstname(text);
                } else if ("lastname".equals(event.asEndElement().getName().getLocalPart())) {
                    student.setLastname(text);
                } else if ("nickname".equals(event.asEndElement().getName().getLocalPart())) {
                    student.setNickname(text);
                } else if ("marks".equals(event.asEndElement().getName().getLocalPart())) {
                    student.setMarks(text);
                }
            } else if (event.isCharacters()) {
                text = event.asCharacters().getData();
            }
        }
        logger.info(students.toString());
    }

    /**
     * 生成xml
     * @throws Exception
     */
    @Test
    public void toXml() throws Exception {
        XMLOutputFactory factory = XMLOutputFactory.newInstance();
        XMLStreamWriter writer = factory.createXMLStreamWriter(System.out);
        writer.writeStartDocument("UTF-8", "1.0");
        writer.writeStartElement("school", "class", "http://www.w3.org/TR/html4/school/");

        //第一个学生
        writer.writeStartElement("school", "student", "http://www.w3.org/TR/html4/school/");
        writer.writeAttribute("rollno", "1");
        writer.writeAttribute("school","http://www.w3.org/TR/html4/school/", "age", "10");
        writer.writeStartElement("school", "firstname", "http://www.w3.org/TR/html4/school/");
        writer.writeCharacters("cxx1");
        writer.writeEndElement();
        writer.writeStartElement("lastname");
        writer.writeCharacters("Bob1");
        writer.writeEndElement();
        writer.writeStartElement("nickname");
        writer.writeCharacters("stars1");
        writer.writeEndElement();
        writer.writeStartElement("marks");
        writer.writeCharacters("85");
        writer.writeEndElement();
        writer.writeEndElement();

        //第二个学生
        writer.writeStartElement("student");
        writer.writeAttribute("rollno", "2");
        writer.writeStartElement("firstname");
        writer.writeCharacters("cxx2");
        writer.writeEndElement();
        writer.writeStartElement("lastname");
        writer.writeCharacters("Bob2");
        writer.writeEndElement();
        writer.writeStartElement("nickname");
        writer.writeCharacters("stars2");
        writer.writeEndElement();
        writer.writeStartElement("marks");
        writer.writeCharacters("85");
        writer.writeEndElement();
        writer.writeEndElement();

        //第三个学生
        writer.writeStartElement("student");
        writer.writeAttribute("rollno", "3");
        writer.writeStartElement("firstname");
        writer.writeCharacters("cxx3");
        writer.writeEndElement();
        writer.writeStartElement("lastname");
        writer.writeCharacters("Bob3");
        writer.writeEndElement();
        writer.writeStartElement("nickname");
        writer.writeCharacters("stars3");
        writer.writeEndElement();
        writer.writeStartElement("marks");
        writer.writeCharacters("85");
        writer.writeEndElement();
        writer.writeEndElement();

        writer.writeEndElement();
        writer.writeEndDocument();
    }
}

Student实体类:

package com.abc.demo.general.xml;

/**
 * 学生
 */
public class Student {
    private int rollno;
    private int age;
    private String firstname;
    private String lastname;
    private String nickname;
    private String marks;

    public Student() {}

    public Student(int rollno, int age, String firstname, String lastname, String nickname, String marks) {
        this.rollno = rollno;
        this.age = age;
        this.firstname = firstname;
        this.lastname = lastname;
        this.nickname = nickname;
        this.marks = marks;
    }

    public int getRollno() {
        return rollno;
    }

    public void setRollno(int rollno) {
        this.rollno = rollno;
    }

    public int getAge() {
        return age;
    }

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

    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 getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public String getMarks() {
        return marks;
    }

    public void setMarks(String marks) {
        this.marks = marks;
    }

    @Override
    public String toString() {
        return "Student{" +
                "rollno=" + rollno +
                ", age=" + age +
                ", firstname='" + firstname + '\'' +
                ", lastname='" + lastname + '\'' +
                ", nickname='" + nickname + '\'' +
                ", marks='" + marks + '\'' +
                '}';
    }
}
Student.java

 

posted @ 2020-12-13 17:08  且行且码  阅读(542)  评论(0编辑  收藏  举报