介绍
- xml: 可扩展标记语言,作为数据的一种存储格式或用于存储软件的参数,程序解析此配置文件,就可以达到不修改代码就能更改程序的目的。
- xml数据示例
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person>
<name>猴子</name>
<age>500</age>
</person>
<person>
<name>八戒</name>
<age>300</age>
</person>
</persons>
第一行数据为声明部分。
3. 解析方式
- Dom方式:将整个xml文档加载到内存中,然后进行处理。缺点显然是不适合处理大文件。
- Sax方式:从文档头开始以流的方式不断向下进行解析。
SAX方式解析流程
流程
- 获取解析工厂
- 从解析工厂获取解析器
- 编写处理器
- 加载文档Document注册处理器
- 进行解析, 从当前的类加载器获取文档
- 在使用时第1、2、4、5步可直接复制粘贴,主要是自己动手实现第3步。
示例
代码:
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* 熟悉SAX解析流程
* 1. 获取解析工厂
* 2. 从解析工厂获取解析器
* 3. 编写处理器
* 4. 加载文档Document注册处理器
* 5. 进行解析, 从当前的类加载器获取文档
* @author dxt
*
*/
public class XmlTest01 {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException{
//SAX解析
//1. 获取解析工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
//2. 从解析工厂获取解析器
SAXParser parse = factory.newSAXParser();
//3. 编写处理器,就是去编写PHandler类
//4. 加载文档Document注册处理器
PHandler handler = new PHandler(); //其中PHandler是我们自己写的
//5. 进行解析, 从当前的类加载器获取xmlwendang
parse.parse(Thread.currentThread().getContextClassLoader()
.getResourceAsStream("dxt/basic/p.xml"), handler);
}
}
class PHandler extends DefaultHandler{
@Override
public void startDocument() throws SAXException{
System.out.println("------文档解析开始------");
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes){
//开始解析元素,只关注qName, qName为标签
System.out.println(qName + "--->解析开始");
}
@Override
public void characters(char[] ch, int start, int length){
/*
* 在此方法中获取相应标签内的内容
* 有一点需要注意的是:xml中的换行、缩进产生的空格 会被识别为标签内的内容
* 在使用时,需要处理换行 和 缩进产生的空格
*/
String contents = new String(ch, start, length).trim(); //trim()去掉字符串前后的空格
if(contents.length() > 0){
System.out.println("内容为:" + contents);
}else{
System.out.println("空----空");
}
}
@Override
public void endElement(String uri, String localName, String qName){
//解析元素结束
System.out.println(qName + "--->解析结束");
}
@Override
public void endDocument() throws SAXException{
System.out.println("------文档解析结束------");
}
}
数据:
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person>
<name>猴子</name>
<age>500</age>
</person>
</persons>
结果:
注意点
第3步编写处理器在主程序流程之中并没有代码体现。我们重写的处理器继承类DefaultHandler。
在处理过程中注意标签间的换行和空格。
SAX方式数据处理
数据
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person>
<name>猴子</name>
<age>500</age>
</person>
<person>
<name>八戒</name>
<age>300</age>
</person>
</persons>
代码
Person类:
/**
* Person类
* 为了处理xml数据
* @author dxt
*
*/
public class Person {
private String name;
private int age;
public Person(){}
public Person(String name, int age){
super();
this.name = name;
this.age = age;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return this.age;
}
}
处理代码:
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* 使用SAX处理xml数据
*
* @author dxt
*
*/
public class XmlTest02 {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException{
//1. 获取解析工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
//2. 从解析工厂获取解析器
SAXParser parser = factory.newSAXParser();
//3. 编写处理器
//4. 加载文档注册处理器
PersonHandler phandler = new PersonHandler();
//5. 进行解析
parser.parse(Thread.currentThread().getContextClassLoader()
.getResourceAsStream("dxt/basic/p.xml"), phandler);
// 获取数据 并打印数据
List<Person> persons = phandler.getPersons();
for(Person p:persons){
System.out.println(p.getName() + "--" + p.getAge());
}
}
}
class PersonHandler extends DefaultHandler{
private List<Person> persons;
private Person p;
private String tag; //存储操作的标签
public List<Person> getPersons(){
return persons;
}
@Override
public void startDocument(){
persons = new ArrayList<Person>();
System.out.println("-------文档解析开始-------");
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes){
//遇到person开始标签,则初始化一个person
if(null != qName){
tag = qName; //存储标签名
if(tag.equals("person")){
p = new Person();
}
}
}
public void characters(char[] ch, int start, int length){
String contents = new String(ch, start, length).trim();
if(tag != null){
if(tag.equals("name")){
p.setName(contents);
}else if(tag.equals("age")){
p.setAge(Integer.valueOf(contents));
}
}
}
@Override
public void endElement(String uri, String localName, String qName){
//遇到person结束标签,则说明此p的信息已处理完毕,将其加入队列
if(null != qName){
if(qName.equals("person")){
persons.add(p);
}
}
tag = null;
}
@Override
public void endDocument(){
System.out.println("-------文档解析结束-------");
}
}