sax解析xml
最近工作上不是那么忙,就趁着这样的空档期学习一些平时很少接触到的知识,最近安排了一段时间来学习下网络通信这块,这两天学习了sax解析xml,这里记录一下。
其中遇到了一个很基础的问题: 对arraylist的操作。现在先来总结下arraylist的相关知识:
1.什么是arraylist?--->arrsylist就是传说中的动态数组,也就是array的复杂版本。其中突出的一些特性如下:
*动态地增加和减少元素
*实现了Icollection和Ilist接口
*灵活设置数组大小
2.如何使用arraylist?--->使用add()方法增加元素;使用get()方法获取元素
好了,下面进入正题,利用sax对xml文件进行解析,这里为了测试方便,解析一个本地的xml文件:
1.先来看一下待解析的xml文件内容:
<?xml version="1.0" encoding="UTF-8"?> <persons> <person id="1"> <name>张三</name> <age>24</age> </person> <person id="2"> <name>李四</name> <age>25</age> </person> <person id="3"> <name>王五</name> <age>26</age> </person> </persons>
xml文件存放在assets文件夹下,读取本地xml并转换为inputStream的方法如下:
this.getResources().getAssets().open("xmltest.xml");
2.进入解析的关键步骤,直接上代码,里面有详细注释:
SAXParserFactory saxfac=SAXParserFactory.newInstance();//得到SAX解析工厂类的实例 MySAXHandler mysaxhandler = new MySAXHandler(); try { SAXParser saxparser=saxfac.newSAXParser();//从SAX解析工厂类中获得sax解析器 InputStream is= MainActivity.this.getResources().getAssets().open("xmltest.xml");//将XML文档转换为输入流 saxparser.parse(is,mysaxhandler);//解析xml文档 persons = mysaxhandler.getPersons(); is.close(); Toast.makeText(MainActivity.this,persons.get(0).getName(), 555).show(); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
a.获取sax解析工厂类的实例
b.从sax解析工厂类中获得sax解析器
c.将xml文档转换为输入流
d.调用parse()解析xml文档
3.MySAXHandler类
上述关键步骤中用到了一个类MySAXHandler,这个是sax的精华所在,通过该类实现内容处理器ContentHandler的一些回调方法,具体内容如下:
public ArrayList<Person> getPersons() { return persons; } /* (非 Javadoc) * @see org.xml.sax.helpers.DefaultHandler#startDocument() * 处理文档解析开始事件 */ public void startDocument() throws SAXException { this.persons = new ArrayList<Person>(); System.out.println("开始解析XML文件"); } /* (非 Javadoc) * @see org.xml.sax.helpers.DefaultHandler#endDocument() *处理文档解析结束事件 */ public void endDocument() throws SAXException { System.out.println("结束解析XML文件"); } /* (非 Javadoc) * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes) * 处理元素开始事件 * qName:元素名字 */ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { this.tagName = localName; if(this.tagName.equals("person")){ //遇到根元素 person = new Person(); person.setId(Integer.parseInt(attributes.getValue(0))); } } /* (非 Javadoc) * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int) * 处根据tagName获取标签的内容
*/ public void characters(char[] ch, int start, int length) throws SAXException { Log.e("SAXXmlContentHandler", "根据tagName获取标签的内容"); if (this.tagName != null) { String data = new String(ch, start, length); if (this.tagName.equals("name")) { this.person.setName(data); } else if (this.tagName.equals("age")) { this.person.setAge(Integer.parseInt(data)); } } } /* (非 Javadoc) * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String) * 处理元素结束事件 */ public void endElement(String uri, String localName, String qName) throws SAXException { if(localName.equals("person")){ this.persons.add(person); //添加一个元素到当前列表的末尾 } this.tagName = null; }
a.startDocument()--->处理文档解析开始事件
b.endDocument()--->处理文档解析结束事件
c.startElement()--->处理元素开始事件
d.endElement()--->处理元素结束事件
e.characters()--->处理元素字符的内容
通过以下方法可以获取解析结果:persons.get(0).getName();
期间遇到一个异常:
该异常的出现,大多是因为xml文件的编写不规范导致,经过检查发现,问题出现在:xml文件的最末尾多了一个符号:> 这都是粗心导致的问题,但当时花了好一段时间来发现这问题。