/**
* 这段代码的作用是对于xml的增删该改查,使用的sax解析的方式
*sax和stax解析技术都是基于事件驱动的用到的类为DefaultHandler
*sax常用时间
*startDocument();–文档开始事件
*startElement();—–元素开始事件
*characters();——-文本事件
*endElement();——–元素结束事件
*EndDocument;———文档结束事件
*/
首先我们创建xml文件,具体代码如下
<?xml version="1.0" encoding="UTF-8" standalone="no"?><books>
<book>
<name> 高效java </name>
<pirce>50 </pirce>
</book>
<book>
<name> java编程思想 </name>
<pirce> 80 </pirce>
</book>
</boos>
/**
*
*/
package com.effective_java;
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;
/**
* @author 干枯的骆驼 了解基本的sax解析技术
*/
public class Model7 {
/**
* @param args
* @throws SAXException
* @throws ParserConfigurationException
*/
public static void main(String[] args) throws Exception {
// TODO 自动生成的方法存根
myhandleter myhandleter = new myhandleter();
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();// 创建sax解析工厂
SAXParser saxParser = saxParserFactory.newSAXParser();// 通过解析工厂得到解析对象
saxParser.parse("text1.xml", myhandleter);// 传递的参数为xml文件和defaultHandler的实现类,所以我们要创建继承一个了defaulthandlter的类
// 通过解析对象解析xml
}
}
class myhandleter extends DefaultHandler {
@Override
public void startDocument() throws SAXException {
// TODO 自动生成的方法存根
super.startDocument();
System.out.println("stratDocument");
}
@Override
public void endDocument() throws SAXException {
// TODO 自动生成的方法存根
super.endDocument();
System.out.println("EndDocument");
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// TODO 自动生成的方法存根
super.startElement(uri, localName, qName, attributes);
System.out.println("StratElement");
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
// TODO 自动生成的方法存根
super.endElement(uri, localName, qName);
System.out.println("EndElement");
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
// TODO 自动生成的方法存根
super.characters(ch, start, length);
System.out.println("characters");
}
}
下面我们来修改信息,获得所有的值
class MyDefaultHeader extends DefaultHandler{
/*
* SAX2 事件处理程序的默认基类。
* 这里方法实在是多,我们就使用其中常用的属性进行重写
*就这几个,大家可能不是特别理解这是什么意思
*大家可以这样理解
*一个DefaultHandler就是一个节点,也就是一个标签
*那么这里就非常好理解了
*startDocument代表文档开始
*endDocument代表的是文档结束
*character代表节点的数据,节点的信息都存在这里
*startElement代表的是文档内的节点开始
*EndElement 代表的是文档内的结束
*
* * */
String nodename;
StringBuilder name;
StringBuilder pirce;
@Override
public void startDocument() throws SAXException {
// System.out.println("文档开始了");
name=new StringBuilder();
pirce=new StringBuilder();
}
@Override
public void endDocument() throws SAXException {
// System.out.println("文档结束了");
}
@Override
public void characters(char[] arg0, int arg1, int arg2)
throws SAXException {
//System.out.println("节点的内容");
if(nodename.equals("name")){
name.append(arg0,arg1,arg2);
}else if(nodename.equals("pirce")){
pirce.append(arg0,arg1,arg2);
}
}
/*
* uri - 名称空间 URI,如果元素没有任何名称空间 URI,或者没有正在执行名称空间处理,则为空字符串。
localName - 本地名称(不带前缀),如果没有正在执行名称空间处理,则为空字符串。
qName - 限定的名称(带有前缀),如果限定的名称不可用,则为空字符串。
attributes - 附加到元素的属性。如果没有属性,则它将是空的 Attributes 对象。
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
nodename=qName;
}
/**
uri - 名称空间 URI,如果元素没有任何名称空间 URI,或者没有正在执行名称空间处理,则为空字符串。
localName - 本地名称(不带前缀),如果没有正在执行名称空间处理,则为空字符串。
qName - 限定的名称(带有前缀),如果限定的名称不可用,则为空字符串。
*/
@Override
public void endElement(String uri, String localname, String qname)
throws SAXException {
//System.out.println("元素结束");
if("book".equals(qname)){
System.out.println(name.toString().trim());
System.out.println(pirce.toString().trim());
/*
在这里你必须使用trim()函数解决空格问题
因为产生的空格会造成判断错误,举个例子,请看下面例子
*/
name.setLength(0);
pirce.setLength(0);
}
}
}
结果如下
看下面例子我做查询检索数据
其他都一样,我们修改endElement方法
查询pirce>60的书的信息
public void endElement(String uri, String localname, String qname)
throws SAXException {
//System.out.println("元素结束");
if("book".equals(qname)){
if(Integer.parseInt(pirce.toString())>60){
System.out.println(name.toString());
System.out.println(pirce.toString());
name.setLength(0);
pirce.setLength(0);
}
}
结果真的哭了
傻逼的我还以为自己智商有问题
结果发现就是自己智商有问题
加上trim();方法
然后我又继续尝试
public void endElement(String uri, String localname, String qname)
throws SAXException {
//System.out.println("元素结束");
if("book".equals(qname)){
if(Integer.parseInt(pirce.toString().trim())>60){
System.out.println(name.toString());
System.out.println(pirce.toString());
name.setLength(0);
pirce.setLength(0);
}
}
TMD结果还是这样
结果这下真的哭了
然后我继续排查
代码修改如下,我用了一个方法封装了打印的操作
@Override
public void endElement(String uri, String localname, String qname)
throws SAXException {
//System.out.println("元素结束");
if("book".equals(qname)){
System.out.print(Integer.parseInt(pirce.toString().trim())>=60?print(name, pirce):false);
name.setLength(0);
pirce.setLength(0);
}
}
}
private boolean print(StringBuilder name,StringBuilder pirce){
System.out.println(name.toString().trim());
System.out.println(pirce.toString().trim());
return true;
}
用到了三目运算符,具体的原因我还不太清楚,我当时猜是因为换行
当也不太确定,知道答案的请回复我,谢谢
我就说到这了,具体的大家自己查看api就知道了,大致来说上面就是一个模板,我们通过对endElement()方法的操作,就能达到数据检索的作用,在开发中,往往会对xml解析,获得对应的值,就相当于一个数据库一样,当然对应的还有序列化,将数据集合序列化为xml元素,如果想了解,可以自己上网查,也可以看我后续的博客