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, start, length); } @Override public void endElement(String uri, String localName, 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, localName, 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, 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); }
3.处理完每个XML元素。
也就是遇到</book>这种结束标记的时候会触发endElement方法。在该事件中能够获得当前处理完元素的所有信息。
public void endElement(String uri, String localName, 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, localName, qName); }
4.处理完XML文件。假设SAX引擎将整个XML文件所有扫描完就会出发endDocument方法。这种方法可能不是必须的,但在这种方法中能够完毕一些收尾工作。比方说释放资源等。在该例中我没有使用。
5.读取字符分析点。
这是一个非常重要的分析点。
假设没有这个分析点。 前面的工作相当于白做,尽管扫描了XML文件,可是没有保存.....而这个分析点所相应的characters事件方法的主要作用就是保存SAX读取的XML文件内容。
详细的说就是<book ... ...>12</book>中的“12”
public void characters(char[] ch, int start, int length) throws SAXException { // TODO Auto-generated method stub stringBuffer.append(ch,start,length); super.characters(ch, start, 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
版权声明:本文博客原创文章。博客,未经同意,不得转载。