需要解析或者序列化的XML文件如下:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?> <Persons> <Person Id="0"> Hello World <Age>20</Age> <Name>zhang0</Name> </Person> <Person Id="1">Hello World <Age>21</Age> <Name>zhang1</Name> </Person> <Person Id="2">Hello World <Age>22</Age> <Name>zhang2</Name> </Person> <Person Id="3">Hello World <Age>23</Age> <Name>zhang3</Name> </Person> <Person Id="4">Hello World <Age>24</Age> <Name>zhang4</Name> </Person> </Persons>
一、XML序列化
/** * 往/data/data/包名/files/person.xml里生成XML数据 * @param personList * @return true 序列化成功 false 序列化失败 */ private boolean mXMLSerializer(List<Person> personList){ try { //获取XML序列化对象 XmlSerializer serializer = Xml.newSerializer(); //文件流对象 FileOutputStream fos = openFileOutput("person.xml",Context.MODE_PRIVATE); //序列化对象往文件流里写数据 serializer.setOutput(fos,"utf-8"); //开始序列化,对应于<?xml version='1.0' encoding='utf-8' standalone='yes' ?> serializer.startDocument("utf-8",true); //开始标签,对应于<Persons> serializer.startTag(null,"Persons"); for(int i=0; i<personList.size(); i++){ serializer.startTag(null,"Person"); serializer.attribute(null,"Id",String.valueOf(personList.get(i).getId())); serializer.text("Hello World"); serializer.startTag(null,"Age"); serializer.text(String.valueOf(personList.get(i).getAge())); serializer.endTag(null,"Age"); serializer.startTag(null,"Name"); serializer.text(personList.get(i).getName()); serializer.endTag(null,"Name"); serializer.endTag(null,"Person"); } serializer.endTag(null,"Persons"); serializer.endDocument(); return true; } catch (Exception e) { e.printStackTrace(); } return false; }
二、XML解析
1、Pull解析:
PULL解析器的运行方式和SAX类似,都是基于事件的模式。不同的是,在PULL解析过程中,我们需要自己获取产生的事件然后做相应的操作,而不像SAX那样由处理器触发一种事件的方法,执行我们的代码。PULL解析器小巧轻便,解析速度快,简单易用,非常适合在Android移动设备中使用,Android系统内部在解析各种XML时也是用PULL解析器。
private List<Person> mXMLPullParse(){ try { //获取PULL解析器对象 XmlPullParser parser = Xml.newPullParser(); //文件输入流 FileInputStream fis = openFileInput("person.xml"); //把解析器和文件输入流绑定 parser.setInput(fis,"utf-8"); //解析器的事件 int eventType = parser.getEventType(); List<Person> personList = null; String name = null; Person person = null; //只要读到的事件不是文件的结束,就继续循环 while(eventType != XmlPullParser.END_DOCUMENT){ name = parser.getName(); switch (eventType) { //开始标签,类似于<Persons> <Person> <Age>之类的 case XmlPullParser.START_TAG: if("Persons".equals(name)){ personList = new ArrayList<Person>(); } else if("Person".equals(name)){ person = new Person() ; //获得该标签的属性 String id = parser.getAttributeValue(null,"Id"); person.setId(Integer.parseInt(id)); } else if("Age".equals(name)){ //获得该标签里的值 <Age>19</Age> 即19 String age = parser.nextText(); person.setAge(Integer.parseInt(age)); } else if("Name".equals(name)){ person.setName(parser.nextText()); } break; case XmlPullParser.END_TAG: if("Person".equals(name)){ personList.add(person); } else if("Persons".equals(name)){ return personList; } break; case XmlPullParser.TEXT: //对应于 Hello World Log.i("XmlPullParser",parser.getText()); break; default: break; } //使解析事件往下走 eventType = parser.next(); } } catch (Exception e) { e.printStackTrace(); } return null; }
2、DOM解析
DOM是基于树形结构的的节点或信息片段的集合,允许开发人员使用DOM API遍历XML树、检索所需数据。分析该结构通常需要加载整个文档和构造树形结构,然后才可以检索和更新节点信息。
由于DOM在内存中以树形结构存放,因此检索和更新效率会更高。但是对于特别大的文档,解析和加载整个文档将会很耗资源,所以Android中使用此方式解析XML并不常见。
/** * DOM解析XML * @param is 输入流 * @return 异常返回null */ public static List<Person> mParse(InputStream is) { try { // 获得DOM解析工厂对象 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); // 获得DOM对象 DocumentBuilder builder = dbf.newDocumentBuilder(); // 解析输入流,得到文档对象 Document document = builder.parse(is); // 获得文档对象的根元素 Element root = document.getDocumentElement(); // 由根元素对象获得标签名字为Peson的一个集合 NodeList childNodes = root.getElementsByTagName("Person"); Person person = null; List<Person> personList = new ArrayList<Person>(); // 遍历该集合 for (int i = 0; i < childNodes.getLength(); i++) { person = new Person(); // 获得子节点,强转为元素。假如i=0,那么就是第一个<Person></Person>这样的节点。 Element item = (Element) childNodes.item(i); // 获得<Person Id="5">这里的"5" person.setId(Integer.parseInt(item.getAttribute("Id"))); // 再次获取<Person>节点里的子节点集合 NodeList childNodes2 = item.getChildNodes(); for (int j = 0; j < childNodes2.getLength(); j++) { // 获取子节点里每个节点。 Node item2 = childNodes2.item(j); // 判断是否为元素节点。 // <Person> // Hello World :第一个子节点 // <Age></Age> :第二个子节点 // </Person> // 像上面的这个例子中,Person节点里就有两个子节点,一个是Hello一个是<Age></Age>,只有Age才是元素节点 if (item2.getNodeType() == Node.ELEMENT_NODE) { Element e = (Element) item2; if ("Age".equals(e.getNodeName())) { // e.getFirstChild().getNodeValue(),如果是上面的这个例子,会获取Hello这个内容。 person.setAge(Integer.parseInt(e.getFirstChild() .getNodeValue())); } else if ("Name".equals(e.getNodeName())) { person.setName(e.getFirstChild().getNodeValue()); } } } personList.add(person); } return personList; } catch (Exception e) { e.printStackTrace(); } return null; }
3、SAX解析
SAX(Simple API for XML)解析器是一种基于事件的解析器,它的核心是事件处理模式,主要是围绕着事件源以及事件处理器来工作的。当事件源产生事件后,调用事件处理器相应的处理方法,一个事件就可以得到处理。在事件源调用事件处理器中特定方法的时候,还要传递给事件处理器相应事件的状态信息,这样事件处理器才能够根据提供的事件信息来决定自己的行为。SAX解析器的优点是解析速度快,占用内存少。非常适合在Android移动设备中使用。
(1)定义一个类,继承与DefaultHandler类,代码如下:
public class SAXHandler extends DefaultHandler { private String content; private List<Person> personList; private Person person; //获取解析的内容 public List<Person> getPersonList(){ return personList; } @Override public void characters(char[] ch,int start,int length) throws SAXException { super.characters(ch,start,length); //获取对应的解析值 content = new String(ch,length); } @Override public void endDocument() throws SAXException { super.endDocument(); Log.i("endDocument","--------endDocument---------"); } @Override public void endElement(String uri,String localName,String qName) throws SAXException { super.endElement(uri,localName,qName); if("Age".equals(localName)){ person.setAge(Integer.parseInt(content)); } else if("Name".equals(localName)){ person.setName(content); } else if("Person".equals(localName)){ personList.add(person); } } @Override public void startDocument() throws SAXException { super.startDocument(); Log.i("startDocument","-------startDocument---------"); personList = new ArrayList<Person>(); } @Override public void startElement(String uri,String qName,Attributes attributes) throws SAXException { super.startElement(uri,qName,attributes); if("Person".equals(localName)){ person = new Person(); person.setId(Integer.parseInt(attributes.getValue("Id"))); } } }
(2)SAX解析类
/** * SAX解析XML * @param is 输入流 * @return 异常返回null */ public static List<Person> mParse(InputStream is) { try { //获得SAX解析工厂对象 SAXParserFactory factory = SAXParserFactory.newInstance(); //获得SAX解析对象 SAXParser saxParser = factory.newSAXParser(); SAXHandler saxHandler = new SAXHandler(); //SAX解析,参数为输入流和DefaultHandler的子类 saxParser.parse(is,saxHandler); List<Person> personList = saxHandler.getPersonList(); return personList; } catch (Exception e) { e.printStackTrace(); } return null; }原文链接:/xml/298481.html