SAX解析:
- Java JDK自带的解析(SAXParserFactory SAXPaeser DefaultHandler)
- 特点:一行一行的往下面执行解析的
- startDocment startelement characters endElement endDocment
解析步骤:
1.创建一个SAXParserFactory对象
SAXParserFactory factory=SAXParserFactory.newInstance();
2.获得解析器
SAXParser parser=factory.newSAXParser();
3.调用解析方法解析xml,这里的第一个参数可以传递文件、流、字符串、需要注意第二个参数(new DefaultHander)
File file=new File("girls.xml");
parser.parse(file,new DefaultHandler());
/**注解:--->这里的DefaultHandler表示
DefaultHandler类是SAX2事件处理程序的默认基类。它继承了EntityResolver、DTDHandler、
ContentHandler和ErrorHandler这四个接口。包含这四个接口的所有方法,所以我们在编写事件处理程序时,
可以不用直接实现这四个接口,而继承该类,然后重写我们需要的方法,所以在这之前我们先定义一个用于实现解析
方法如下:*/
4.创建一个MyHandler类来继承DefaultHandler并重写方法
//定一个名为MyHandler类用来继承DefaultHandler
(1)MyHandler extends DefaultHander
(2)重写方法,快速记住方法(2个开始,2个结束,1一个文字(charactor--里面的内容))
(3)2个开始:StartDocment(文档的开始)StartElement(元素的开始) 2个结束:endElement(元素的结束)
endDocment(文档的结束,标志着xml文件的结束) 1个文字内容:charactor(文字内容)
5.创建一个集合把所解析的内容添加到集合
//分析:目的我们只是需要把xml里面的文字内容添加到我们的集合而不需要其他元素,所以我们需要进行判断得到
//(接上)我们需要的内容(下面会赋一个图帮助理解)
6.接步骤三 输出集合System.out.pritnln(list); 解析完成!
记住这张图:
一个列子:
- 我们将对这个xml文件进行SAX解析
第一步初始化一个Girl类:
/**
*老套路 封装属性 setter getter toString
* @author sKy°
* @date 2016-5-5
* @version 1.0
*/
public class Girl {
private String id;
private String name;
private String age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public String toString() {
return "Girl [name=" + name + ", age=" + age + "]";
}
}
第二步继承DefaultHandler:
* 继承Default
* 一个用来处理girls 里面XML 数据的处理器
* 配合SAXParser一起使用 目标:想要将girls
* 里面的数据,存在一个集合里面以备后面使用
*
* 获取五种方法
* startDocment startElement
* characters endDocment endElement
* @author sKy°
* @date 2016-5-5
* @version 1.0
*/
public class MyHandler extends DefaultHandler {
// 准备一个用于添加xml数据的集合、调用Girl类、准一个用于用来保存开始的标签的tag
private List<Girl> girls;
private Girl girl;
private String tag;
@Override
public void startDocument() throws SAXException {
super.startDocument();
// 因为这个方法只调用一次,所以在开始的时候就可以实例化集合
girls=new ArrayList<>();
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
// 这个方法,只有当开始一个元素的时候才会调用,
// 通过分析,当外部开始元素为girl的时候,需要将girl实例化
// 将tag赋值
tag=qName;
if ("girl".equals(qName)) {
girl=new Girl();
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
super.endElement(uri, localName, qName);
// 这句话,必须写,因为,当sax解析完一个元素的时候,会自动认为换行符是一个字符,会继续执行 character 方法 。如果不写,就会造成没有数据的现象。
tag="";
// 这个方法,当到了元素结尾的时候,会调用,应该在这里,将对象添加到集合里面去。
if ("girl".equals(qName)) {
girls.add(girl);
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
super.characters(ch, start, length);
// 这里是内容,但是,无法直接判断属于哪一个元素。
String string = new String(ch, start, length);
if ("name".equals(tag)) {//判断当前内容,属于哪一个元素。
girl.setName(string);
}else if ("age".equals(tag)) {
girl.setAge(string);
}//这两种情况,表示 当前语句执行在 girls 标签内。
}
// 外部设置和获得值(getter setter)
public List<Girl> getGirls() {
return girls;
}
public void setGirls(List<Girl> girls) {
this.girls = girls;
}
public Girl getGirl() {
return girl;
}
public void setGirl(Girl girl) {
this.girl = girl;
}
}
第三步解析:
* SAX解析步骤
* @author sKy°
* @date 2016-5-5
* @version 1.0
*/
public class Sax03 {
public static void main(String[] args) {
// 1.创建对象
SAXParserFactory newInstance = SAXParserFactory.newInstance();
try {
// 2.获取解析器
SAXParser saxParser = newInstance.newSAXParser();
// 3.调用方法开始解析xml
File file = new File("girls.xml");
MyHandler dh = new MyHandler();
saxParser.parse(file, dh);
List<Girl> girls=dh.getGirls();
// 4.输出集合
System.out.println(girls);
} catch (ParserConfigurationException | SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
最后的解析结果:
(因为这个是先解析好了 后面才加的id属性 所以没有对id这段进行解析 )