大概思路: 1.首先我们通过输入流来获取要读取的xml文件。 2xml是存放一个对象的数据源,具体对象中的属性我们不知道,那么我们就需要利用反射来读取对象中的属性,利用反射来创建对象,给对象赋值。 3.开始解析,执行开始文档的方法,<> 开始标签里面有值就可以利用attributes.getValue()方法来获取值. 4.读取到属性调用 characters()方法将属性存起来,到结束文档的方法 5结束解析,执行开始文档的方法</>就代表读完一个对象,将对象存入集合
1.提供返回数据源的方法
public ArrayList saxReadXML(InputStream is,Class aClass) throws Exception { this.aClass=aClass; SAXParserFactory factory = SAXParserFactory.newInstance();//获得解析工厂 SAXParser parser = factory.newSAXParser();//获得解析器 parser.parse(is,new SaxHepler());//加载要解析的数据 return list; }2.封装DefaultHandler解析类
class SaxHepler extends DefaultHandler{ @Override public void startDocument() throws SAXException { super.startDocument();//文档开始 } @Override public void endDocument() throws SAXException { super.endDocument();//文档结束 } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { super.startElement(uri, localName, qName, attributes); /** * 获得这个类的名字转小写 * 1.例:<sudent> 的这个对象是Student ,转成student */ String name = aClass.getSimpleName().toLowerCase(); if(qName.equals(name)){ try { object= aClass.newInstance();//创建这个class对象 } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } Field[] declaredFields = aClass.getDeclaredFields();//获得这个class对象的字段 for (int i=0;i<declaredFields.length;i++){ //attributes 这个参数就是开始标签里的属性 例:<Student id="1" name="张三"> for(int j=0;j<attributes.getLength();j++){ String name1 = declaredFields[i].getName();//获取这个标签名 String qName1 = attributes.getQName(j);//获取标签里的值 if(name1.equals(qName1)){ try { declaredFields[i].set(object,attributes.getValue(j));//给这个对象设置值 } catch (IllegalAccessException e) { e.printStackTrace(); } } } } } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { super.endElement(uri, localName, qName); String name = aClass.getSimpleName().toLowerCase();//同上 Field[] declaredFields = aClass.getDeclaredFields();//获取这个对象里的属性 if(qName.equals(name)){//如果判断结束了</student> 那么就将这个对象存入集合 list.add(object); } for (int i=0;i<declaredFields.length;i++){//通过属性字段来遍历每一个属性 String name1 = declaredFields[i].getName();//获得每个字段的属性名字 if(qName.equals(name1)){ try { declaredFields[i].set(object,string);//设置值 } catch (IllegalAccessException e) { e.printStackTrace(); } } } } @Override public void characters(char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); string=new String(ch,start,length);//存起来 } }3.使用的写法
River student=null; try { InputStream open = getAssets().open("rivers.xml"); ArrayList<River> arrayList = new SaxTool().saxReadXML(open, River.class); for(int i=0;i<arrayList.size();i++){ student= arrayList.get(i); textView.append(student.toString()+"\n"); } } catch (Exception e) { e.printStackTrace(); }4.解析的XML文件
<?xml version="1.0" encoding="utf-8"?> <rivers> <river name="灵渠" length="605"> <introduction> 灵渠在广西壮族自治区兴安县境内,是世界上最古老的运河之一,有着“世界古代水利建筑明珠”的美誉。灵渠古称秦凿渠、零渠、陡河、兴安运河,于公元前214年凿成通航,距今已2217年,仍然发挥着功用。 </introduction> <imageurl> http://imgsrc.baidu.com/baike/pic/item/389aa8fdb7b8322e08244d3c.jpg </imageurl> </river> <river name="胶莱运河" length="200"> <introduction> 胶莱运河南起黄海灵山海口,北抵渤海三山岛,流经现胶南、胶州、平度、高密、昌邑和莱州等,全长200公里,流域面积达5400平方公里,南北贯穿山东半岛,沟通黄渤两海。胶莱运河自平度姚家村东的分水岭南北分流。南流由麻湾口入胶州湾,为南胶莱河,长30公里。北流由海仓口入莱州湾,为北胶莱河,长100余公里。 </introduction> <imageurl> http://imgsrc.baidu.com/baike/pic/item/389aa8fdb7b8322e08244d3c.jpg </imageurl> </river> <river name="苏北灌溉总渠" length="168"> <introduction> 位于淮河下游江苏省北部,西起洪泽湖边的高良涧,流经洪泽,青浦、淮安,阜宁、射阳,滨海等六县(区),东至扁担港口入海的大型人工河道。全长168km。 </introduction> <imageurl> http://imgsrc.baidu.com/baike/pic/item/389aa8fdb7b8322e08244d3c.jpg </imageurl> </river> </rivers>