android 或者java SAX解析XML
- - ITeye博客本实例解析xml使用的是继承DefaultHandler类,此类就是java中封装好的xml解析器类,下面看代码详细说明:. 第一步:首先说明下xml文件,Java Sax解析是按照xml文件的顺序一步一步的来解析,在解析xml文件之前,我们要先了解xml文件的节点的种类,一种是ElementNode,一种是TextNode.
本实例解析xml使用的是继承DefaultHandler类,此类就是java中封装好的xml解析器类,下面看代码详细说明:
第一步:首先说明下xml文件,Java Sax解析是按照xml文件的顺序一步一步的来解析,在解析xml文件之前,我们要先了解xml文件的节点的种类,一种是ElementNode,一种是TextNode。如下面的这段people.xml,其中,像<people>、<person>这种节点就属于ElementNode,而张三这种就属于TextNode,001属于Attributes的值。
<?xml version="1.0" encoding="UTF-8"?> <people> <person personid="001"> <name>张三</name> <tel>12345</tel> </person> <person personid="002"> <name>李四</name> <tel>678910</tel> </person> </people>
第二步:我们为了代码的复用性高点我们先继承DefaultHandler创建一个BaseHandler基础的解析器抽象类,详细说明和代码如下:
import java.io.File; import java.io.InputStream; import java.io.StringReader; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; public abstract class BaseHandler extends DefaultHandler { // 解析时导入的是xml字符串 public boolean parse(String xmlString) { return false; }; // 解析时导入的是xml流 public boolean parse(InputStream xmlInputStream) { return false; }; // 解析时导入的是xml的File类型数据 public boolean parse(File file) { return false; }; public void parserXml(BaseHandler baseHandler, String xmlString) throws Exception { if (xmlString == null || xmlString.length() == 0) return; //注册baseHandler事件并获取XMLReader实例 XMLReader xmlReader = xmlReader(baseHandler); //将字符串转换成StringReader对象 StringReader read = new StringReader(xmlString); //将字StringReader对象转换成InputSource对象 InputSource source = new InputSource(read); //将一个xml字符串变成一个java可以处理的InputSource对象载入xmlReader的parse方法中,解析正式开始 xmlReader.parse(source); read.close(); } //把自己写的baseHandler注册到XMLReader中并返回XMLReader对象 private XMLReader xmlReader(BaseHandler baseHandler) { //获得解析工厂的实例 SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser; XMLReader xmlReader = null; try { //获得工厂解析器 parser = factory.newSAXParser(); //从SAXPsrser中得到一个XMLReader实例 xmlReader = parser.getXMLReader(); //把自己写的baseHandler注册到XMLReader中(注册处理XML文档解析事件ContentHandler) xmlReader.setContentHandler(baseHandler); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return xmlReader; } public void parserXml(BaseHandler baseHandler, InputStream xmlInputStream) throws Exception { if (xmlInputStream == null) return; //获得解析工厂的实例 SAXParserFactory factory = SAXParserFactory.newInstance(); //获得工厂解析器 SAXParser parser = factory.newSAXParser(); //将一个xml流载入parse方法中,解析正式开始 parser.parse(xmlInputStream, baseHandler); } public void parserXml(BaseHandler baseHandler, File file) throws Exception { if (file == null) return; //获得解析工厂的实例 SAXParserFactory factory = SAXParserFactory.newInstance(); //获得工厂解析器 SAXParser parser = factory.newSAXParser(); //将一个xml文件对象File载入parse方法中,解析正式开始 parser.parse(file, baseHandler); } /* * 读取标签里的值,ch用来存放某行的xml的字符数据,包括标签,初始大小是2048, 每解释到新的字符会把它添加到char[]里。 * * 注意,这个char字符会自己管理存储的字符, 并不是每一行就会刷新一次char,start,length是由xml的元素数据确定的, * 这里一个正标签,反标签都会被执行一次characters,所以在反标签时不用获得其中的值 * 这里获取的值是标签之间的值如:<item>*********</item>表示星号部分的值 */ public abstract void characters(char[] ch, int start, int length) throws SAXException; // 用户处理文档解析结束事件 public void endDocument() throws SAXException{}; // 用于处理元素结束事件 public abstract void endElement(String uri, String localName, String qName) throws SAXException; // 用于处理文档解析开始事件 public void startDocument() throws SAXException{}; /* * 用于处理元素开始事件, * 在解释到一个开始元素时会调用此方法.但是当元素有重复时可以自己写算法来区分 这些重复的元素.qName是什么? * <name:page ll=""></name:page>这样写就会抛出SAXException错误 通常情况下qName等于localName */ public abstract void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException; }
第三步:我们针对自己编写的people.xml文件作为本例解析文件做一个对应的PeopleHandler类继承基础类BaseHandler,实现如下:
import java.io.File; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Stack; import org.xml.sax.Attributes; import org.xml.sax.SAXException; public class PeopleHandler extends BaseHandler { private Person mPerson; //实例化一个栈用于存放标签 private Stack<String> tagStack = new Stack<String>(); //实例化一个集合存储Person对象 private List<Person> list = new ArrayList<Person>(); @Override public void characters(char[] ch, int start, int length) throws SAXException { String chars = new String(ch, start, length).trim(); if (chars != null) { String tagName = (String) tagStack.peek();//从栈中获取一个标签元素 if (tagName.equals("name")) { mPerson.setName(chars); } else if (tagName.equals("tel")) { mPerson.setTel(chars); } } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { tagStack.pop();//当一个标签把他弹出栈 if (qName.equals("person")) {//当一个person标签结束时将mPerson对象添加到list集合中 list.add(mPerson); } } @Override public boolean parse(String xmlString) { try { super.parserXml(this, xmlString); return true; } catch (Exception e) { e.printStackTrace(); return false; } } @Override public boolean parse(InputStream xmlInputStream) { try { super.parserXml(this, xmlInputStream); return true; } catch (Exception e) { e.printStackTrace(); return false; } } @Override public boolean parse(File file) { try { super.parserXml(this, file); return true; } catch (Exception e) { e.printStackTrace(); return false; } } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (qName.equals("person")) {//当一个person标签开始时实例化一个Person对象 mPerson = new Person(); String personId = attributes.getValue("personid");//获取person标签中的属性值personId mPerson.setPersonID(personId); } tagStack.push(qName); } public List<Person> getResult(){ return list; } public void clear(){ list.clear(); } }
第四步:编写一个测试类main进行测试验证:
import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; public class Mian { public static void main(String[] args) { // 实例化自定义的解析类 PeopleHandler mHandler = new PeopleHandler(); // 载入解析对象这里使用三种方式 // 第一种:载入xml的File类型进行解析 String filename = "src/people.xml"; File file = new File(filename); mHandler.parse(file); System.out.println("第一种方式实现输出结果:" + mHandler.getResult()); mHandler.clear(); // 第二种:载入xml流的方式进行解析 try { InputStream is = new FileInputStream(file); mHandler.parse(is); System.out.println("第二种方式实现输出结果:" + mHandler.getResult()); mHandler.clear(); } catch (FileNotFoundException e) { e.printStackTrace(); } // 第三种:载入xml字符串的方式进行解析 try { InputStreamReader insReader = new InputStreamReader( new FileInputStream(file), "UTF-8"); BufferedReader bufReader = new BufferedReader(insReader); StringBuffer str = new StringBuffer(); String line; while ((line = bufReader.readLine()) != null) { str.append(line); } bufReader.close(); insReader.close(); mHandler.parse(str.toString()); System.out.println("第三种方式实现输出结果:" + mHandler.getResult()); mHandler.clear(); } catch (IOException e) { e.getStackTrace(); } } }