首先创建一个学生对象:
package javaxml;
public class Student {
private String stuno;
private String name;
private String address;
private Integer age;
public String getStuno() {
return stuno;
}
public void setStuno(String stuno) {
this.stuno = stuno;
}
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 Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
建立一个与student对象向对应的xml文件对象,在该xml对象当中存放着要进行实例化的学生对象的信息
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student stuno="001">
<name>qingzhiyu</name>
<age>22</age>
<address>china</address>
</student>
<student stuno="002">
<name>zhouxiaoqing</name>
<age>22</age>
<address>xiamen</address>
</student>
</students>
定义用于对xml文件进行解析并将xml文件当中的信息转变为一个对应对象的解析器类。在该类当中定义了具体的解析规则:
package javaxml;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.sax.SAXTransformerFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
*
* @author Administrator
* 对父类当中的方法进行重写操作
* 1:startDocument()在开始对xml文件对象进行加载的时候将会触发该方法
* 2:endDocument()在对xml文件进行解析完毕之后的时候调用该方法
* 3:startElement()在对xml文件对象当中的标签开始进行解析的时候调用该方法
* 4:endElement()在对xml文件对象当中的结束标签进行加载的时候调用该方法
* 5:characters()在对标签当中的数据信息进行读取的时候调用该方法
* 当前类当中定义了具体如何对xml文件对象当中的信息进行解析并将该信息变为一个实例化对象
*/
public class SAXParseUtil extends DefaultHandler{
// 实例化一个students集合对象并为其设置set和get方法
private List<Student> students=new ArrayList<Student>();
private Student student=null;
private String message=null;
private String tag=null;
/**
* @return the students
*/
public List<Student> getStudents() {
return students;
}
/**
* @param students the students to set
*/
public void setStudents(List<Student> students) {
this.students = students;
}
/* (non-Javadoc)
* @see org.xml.sax.helpers.DefaultHandler#startDocument()
*/
@Override
public void startDocument() throws SAXException {
//开始对xml文件对象进行解析
super.startDocument();
}
/* (non-Javadoc)
* @see org.xml.sax.helpers.DefaultHandler#endDocument()
*/
@Override
public void endDocument() throws SAXException {
//对xml文件对象解析完毕
super.endDocument();
}
/* (non-Javadoc)
* @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
* qName当前所指向的开始标签的名字
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
tag=qName;
System.out.println("**************************开始进行"+qName+"标签解析*******************************");
if(qName!=null&&qName.equals("student")){//如果是student开始节点
String stuno=attributes.getValue("stuno");//获取stuno属性
// System.out.println(stuno);
student =new Student();
student.setStuno(stuno);
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if(qName!=null&&qName.equals("student")){
students.add(student);
}
tag="";
System.out.println("**************************结束"+qName+"标签解析*******************************");
}
/* (non-Javadoc)
* @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
* ch数组当中所拥有的内容
[
,
, <, s, t, u, d, e, n, t, s, >,
,
, , , <, s, t, u, d, e, n, t, , s, t, u, n, o, =, ", 1, 0, 0, 1, ", >,
,
, , , , , , <, n, a, m, e, >, J, O, N, E, S, <, /, n, a, m, e, >,
,
, , , <, a, g, e, >, 2, 0, <, /, a, g, e, >,
,
, , , <, a, d, d, r, e, s, s, >, 北, 京, <, /, a, d, d, r, e, s, s, >,
,
, , , <, /, s, t, u, d, e, n, t, >,
,
, , , <, s, t, u, d, e, n, t, , s, t, u, n, o, =, ", 1, 0, 0, 2, ", >,
,
, , , , , , <, n, a, m, e, >, S, M, I, T, H, <, /, n, a, m, e, >,
,
, , , <, a, g, e, >, 2, 1, <, /, a, g, e, >,
,
, , , <, a, d, d, r, e, s, s, >, 天, 津, <, /, a, d, d, r, e, s, s, >,
,
, , , <, /, s, t, u, d, e, n, t, >,
,
, <, /, s, t, u, d, e, n, t, s, >,
又ch字符数组当中的内容可以知道,该数组当中其实就是存放的要进行具体解析的xml文件
当当前所要进行解析的对象tag为name的时候程序将会自动的将name标签当中的value在字符数组当中所在的位置传值该start,将value当中的长度传值给length
然后将字符数组当中指定位置处的字符转变为string类型数据
*/
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if(tag!=null&&tag.equals("name")){//如果遇到name标签,则获取该name中文本内容
String name= new String(ch,start,length);
student.setName(name);
}else if(tag!=null&&tag.equals("age")){
String age= new String(ch,start,length);
student.setAge(age);
}else if(tag!=null&&tag.equals("address")){
String address= new String(ch,start,length);
student.setAddress(address);
}
}
}
在完成以上操作之后就可以实现对xml文件进行解析操作
1:建立解析工厂
2:获取解析器
3:实例化处理器(即对xml文件进行解析规定的类)
4:通过输入流来对xml文件进行读取操作
5:调用解析器当中的方法来实现解析
package javaxml;
import java.io.InputStream;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;
import com.sun.org.apache.xml.internal.resolver.readers.SAXParserHandler;
public class SAXTest {
public static void main(String[] args) throws Exception, SAXException
{
// 1:建立一个SAXFactory工厂实例化对象
SAXParserFactory factory=SAXParserFactory.newInstance();
// 2:实例化一个解析器对象
SAXParser parser=factory.newSAXParser();
// 3:实例化一个解析处理器,定义具体的xml文件对象解析规则
SAXParseUtil handler=new SAXParseUtil();
// 4:加载xml文件
InputStream inputStream=SAXTest.class.getClassLoader().getSystemResourceAsStream("student.xml");
// 5:调用解析对象当中的解析方法来执行解析
parser.parse(inputStream,handler);
System.out.println("对解析之后所生成的对象进行输出:");
List<Student> students=handler.getStudents();
for (Student student : students)
{
System.out.println(student.getStuno());
System.out.println(student.getName());
System.out.println(student.getAge());
System.out.println(student.getAddress()+"\n");
}
}
}
程序运行结果:
由程序运行之后的结果可以看出解析的时候是按照xml文件当中的内容从上而下逐步进行解析操作的。
且在开始解析xml的时候调用的是
public void startDocument() throws SAXException
然后开始对开始标签进行解析的时候调用的是:
public void startElement(String uri, String localName, String qName,Attributes attributes)方法
之后开始对标签当中的内容部分进行解析(此处解析借用字符数组来对开始和结束标签之间的内容进行了读取)
public void characters(char[] ch, int start, int length)
当对标签中间的内容读取完毕之后,若当前标签中有子标签(子结点的时候)
按照其父节点的形式继续进行解析(与递归类似)
最后开始对当前标签的结束标签进行解析的时候调用
public void endElement(String uri, String localName, String qName)
当对整个xml文件对象解析完毕之后所调用的方法为:
public void endDocument()