SAX即Simple Api for Xml就是一个简单的操作XML数据的一套SUN提供的API机制。
SAX采用的解析的原理是基于事件触发的机制。
SAX技术只能进行XML数据的读取。
1、准备需要解析的XML文件linkmans.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?><linkmans> <linkman> <name>jack</name> <phone>18663243245</phone> <email>jack@163.com</email> </linkman> <linkman> <name>张三</name> <phone>1353243247</phone> <email>zs@126.com</email> </linkman></linkmans>
2. 获取SAX解析器// 2. 获取SAX解析器 public static SAXParser getParser()throws Exception{ // 2.1 获取解析器工厂类对象 SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); return parser; }
3. 解析数据// 3. 解析数据 public static void getElement(File file,DefaultHandler dh)throws Exception{ // 3.1获取解析器 SAXParser parser = getParser(); // 3.2调用解析方法 parser.parse(file, dh); }
4. 创建一个继承自DefaultHandler类的MyHandler.javapublic class MyHandler extends DefaultHandler { // 当文档开始解析的时候自动执行 public void startDocument() throws SAXException { super.startDocument(); System.out.println("XML文档开始解析..."); } // 遇到一个开始元素自动执行 public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { super.startElement(uri, localName, name, attributes); System.out.println("元素"+name+"开始..."); } // 遇到文本内容自动执行 public void characters(char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); System.out.println("文本内容"+new String(ch,start,length)); } // 遇到元素结束自动执行 public void endElement(String uri, String localName, String name) throws SAXException { super.endElement(uri, localName, name); System.out.println("元素"+name+"结束..."); } // 文档解析完毕的时候自定执行 public void endDocument() throws SAXException { super.endDocument(); System.out.println("XML文档解析结束..."); }}
5. 在main函数中调用解析元素的方法public static void main(String[] args)throws Exception { File file = new File("linkmans.xml"); MyHandler handler = new MyHandler(); getElement(file,handler); }
通过以上的程序发现其实SAX解析的时候只是需要开发者传递相应的事件处理器对象即可(继承自DefaultHandler的类)。
举例1:创建一个事件处理器获取XML中的指定的节点数据。public class OptionDataHandler extends DefaultHandler { // 定义一个成员变量记录标签的名 private String name = null; // 定义一个统计次数的变量 private int count = 0; // 遇到一个开始元素自动执行 public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { super.startElement(uri, localName, name, attributes); this.name = name; if("name".equals(this.name)){ this.count++; } } // 遇到文本内容自动执行 public void characters(char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); // 判断是否是name元素 if("name".equals(this.name) && this.count == 2){ System.out.println(new String(ch,start,length)); } }}
案例一: 使用SAX解析XML数据并进行数据的集合封装
其实使用任何的XML解析技术来解析XML数据都需要后期的数据封装,如果只是单独的获取某一个节点的值是没有任何含义的。因此需要将XML的数据解析好之后以对象的方式进行封装到指定的集合中便于其他应用程序的处理。
1. 实现一个Linkman.java的javabean对象public class Linkman { private String name; private String phone; private String email; public Linkman() { super(); } public Linkman(String name, String phone, String email) { super(); this.name = name; this.phone = phone; this.email = email; } // 省略get和set方法}
3. 创建一个用于封装的事件处理器Listhandler.javapublic class ListHandler extends DefaultHandler { // 定义javabean对象 private Linkman linkman = null; // 定义一个集合封装javabean对象 private List<Linkman> list = null; // 定义解析的元素的名字 private String name = null; @Override public void startDocument() throws SAXException { super.startDocument(); // 创建list集合的对象 this.list = new ArrayList<Linkman>(); } @Override public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { super.startElement(uri, localName, name, attributes); // 记录解析的元素的名 this.name = name; // 如果是linkman那么创建一个Linkman对象 if("linkman".equals(this.name)){ this.linkman = new Linkman(); } } @Override public void characters(char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); // 如果此时元素名是name获取文本值 if("name".equals(this.name)){ this.linkman.setName(new String(ch,start,length)); } // 如果此时元素名是phone获取文本值 if("phone".equals(this.name)){ this.linkman.setPhone(new String(ch,start,length)); } // 如果此时元素名是email获取文本值 if("email".equals(this.name)){ this.linkman.setEmail(new String(ch,start,length)); } } @Override public void endElement(String uri, String localName, String name) throws SAXException { super.endElement(uri, localName, name); // 释放this.name this.name = null; // 如果此时的元素名是linkman if("linkman".equals(name)){ // 将linkman对象添加到集合 this.list.add(this.linkman); // 清空linkman对象 this.linkman = null; } } // 对外提供一个获取封装好linkman集合的方法 public List<Linkman> getList() { return list; }}
总结:如果使用SAX进行数据的读取那么一定是一个很好的选择,但是该解析技术不能进行其他的操作比如:增、删和改。
解决方案:可以有一个种技术奖DOM和SAX结合起来即可以高效的查询又可以进行实际的数据操作(增、删和改)。即使用第三方的XML解析技术DOM4J。