💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
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](http://download.csdn.net/detail/tangnengwu/7664719)