Android SDK支持采用SAX技术读取XML,SAX采用顺序读取的方式来处理XML文档。这就要求在每读取XML文档的某个节点时会触发相应的事件来处理这个节点。下面基于一个实例讲述SAX的使用:
public class Book { private String name; private String id; private String price; private String publisher; private int count; .... get,set方法省略 }
XML文件如下:
<?xml version="1.0" encoding="utf-8"?> <books xmlns:book="http://schemas.android.com/com.example.jsonxmlio"> <book book:name="语文" book:id="001" book:price="45" book:publisher="A">12</book> <book book:name="数学" book:id="002" book:price="50" book:publisher="B">10</book> <book book:name="英语" book:id="003" book:price="55" book:publisher="C">21</book> </books>
XMLTool.java
1.构建一个工厂SAXParserFactory
2.构建并实例化SAXPraser对象
public class XMLTool { private static SAXParser getSAXParser() throws ParserConfigurationException,SAXException { SAXParserFactory parserFactory = SAXParserFactory.newInstance(); return parserFactory.newSAXParser(); } public static DefaultHandler parse(InputStream inStream,DefaultHandler handler){ if(inStream!=null){ try { SAXParser parser = getSAXParser(); parser.parse(inStream,handler); return handler; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(inStream!=null){ try { inStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } return null; } }
BookXMLParser.java
public class BookXMLParser extends DefaultHandler { private ArrayList<Book> dataList; private Book book; private StringBuffer stringBuffer = new StringBuffer(); //private StringBuffer buffer=new StringBuffer(); public ArrayList<Book> getData() { return dataList; } public void startDocument() throws SAXException { // TODO Auto-generated method stub dataList = new ArrayList<Book>(); } public void startElement(String uri,String localName,String qName,Attributes attributes) throws SAXException { // TODO Auto-generated method stub if(qName.equals("book")) { book = new Book(); book.setName(attributes.getValue("book:name")); book.setId(attributes.getValue("book:id")); book.setPrice(attributes.getValue("book:price")); book.setPublisher(attributes.getValue("book:publisher")); } super.startElement(uri,localName,qName,attributes); } @Override public void characters(char[] ch,int start,int length) throws SAXException { // TODO Auto-generated method stub stringBuffer.append(ch,start,length); super.characters(ch,length); } @Override public void endElement(String uri,String qName) throws SAXException { // TODO Auto-generated method stub if(qName.equals("book")) { if(stringBuffer.toString()!=null && !stringBuffer.toString().equals("")) { book.setCount(Integer.parseInt(stringBuffer.toString().trim())); stringBuffer.setLength(0);//必须清空缓冲区 } dataList.add(book); } super.endElement(uri,qName); } }
SAX引擎需要处理5个分析点,也可以称为分析事件。
1.开始分析XML文件。该分析点表示SAX引擎刚刚开始处理XML文件,但是还没有读取XML文件中的内容,该分析点对应:
public void startDocument() throws SAXException { // TODO Auto-generated method stub dataList = new ArrayList<Book>(); }
在此方法里面可以做一些初始化的工作。
2.开始处理每一个XML元素。也就是遇到<book>这样的起始标记的时候都会触发这个分析节点,所对应的事件方法是startElement。在这个节点可以获得元素的名称、属性的相关信息。
public void startElement(String uri,Attributes attributes) throws SAXException { // TODO Auto-generated method stub if(qName.equals("book")) { book = new Book(); book.setName(attributes.getValue("book:name")); book.setId(attributes.getValue("book:id")); book.setPrice(attributes.getValue("book:price")); book.setPublisher(attributes.getValue("book:publisher")); } super.startElement(uri,attributes); }
3.处理完每一个XML元素。也就是遇到</book>这样的结束标记的时候会触发endElement方法,在该事件中可以获得当前处理完元素的全部信息。
public void endElement(String uri,String qName) throws SAXException { // TODO Auto-generated method stub if(qName.equals("book")) { if(stringBuffer.toString()!=null && !stringBuffer.toString().equals("")) { book.setCount(Integer.parseInt(stringBuffer.toString().trim())); stringBuffer.setLength(0);//必须清空缓冲区 } dataList.add(book); } super.endElement(uri,qName); }
4.处理完XML文件。如果SAX引擎将整个XML文件全部扫描完就会出发endDocument方法。这个方法可能不是必须的,但在这个方法中可以完成一些收尾工作,比如说释放资源等。在该例中我没有使用。
5.读取字符分析点。这是一个很重要的分析点。如果没有这个分析点, 前面的工作相当于白做,虽然扫描了XML文件,但是没有保存.....而这个分析点所对应的characters事件方法的主要作用就是保存SAX读取的XML文件内容。具体的说就是<book ... ...>12</book>中的“12”
public void characters(char[] ch,length); }
使用SAX解析XML:
public class MainActivity extends Activity { private List<Book> books; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); InputStream inStream = getResources().openRawResource(R.raw.books); BookXMLParser parser = new BookXMLParser(); books = ((BookXMLParser)XMLTool.parse(inStream,parser)).getData(); if(books!=null && books.size()>0) { for(int i = 0;i<books.size();i++) { Log.d("AAA",books.get(i).toString()); } } } }
写XML文件
public static void WriteXML(List<Book> books,OutputStream out) throws Exception { XmlSerializer serializer = Xml.newSerializer(); serializer.setOutput(out,"UTF-8"); serializer.startDocument("UTF-8",true); serializer.startTag(null,"books"); for (Book book : books) { serializer.startTag(null,"book"); serializer.attribute(null,"book:name",book.getName()); serializer.attribute(null,"book:id",book.getId()); serializer.attribute(null,"book:price",book.getPrice()); serializer.attribute(null,"book:publisher",book.getPublisher()); serializer.text(String.valueOf(book.getCount())); serializer.endTag(null,"book"); } serializer.endTag(null,"books"); serializer.endDocument(); out.flush(); out.close(); }
Demo: http://download.csdn.net/detail/tangnengwu/7664719 原文链接:/xml/298321.html