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实体类:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 + '\'' + '}'; } }