您的位置:首页 > 移动开发 > Android开发

Android解析XML文件的三方法

2011-10-27 19:12 441 查看
 
除了可以使用 SAX和DOM解析XML文件,大家也可以使用Android内置的Pull解析器解析XML文件。 Pull解析器的运行方式与 SAX 解析器相似。它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件。事件将作为数值代码被发送,因此可以使用一个switch对感兴趣的事件进行处理。当元素开始解析时,调用parser.nextText()方法可以获取下一个Text类型节点的值。

 

public class PullService {

public static List<Person> readXML(InputStream inputStream) throws IOException{

    XmlPullParser parser = Xml.newPullParser();

    try {

    parser.setInput(inputStream, "UTF-8");

    int eventType = parser.getEventType();

  

    Person currentPerson = null;

    List<Person> persons = null;

    while (eventType != XmlPullParser.END_DOCUMENT) {

     switch (eventType) {

    case XmlPullParser.START_DOCUMENT://文档开始事件,可以进行数据初始化处理

      persons = new ArrayList<Person>();

      break;

    case XmlPullParser.START_TAG://开始元素事件

      String name = parser.getName();

      if (name.equalsIgnoreCase("person")) {

       currentPerson = new Person();

       currentPerson.setId(new Integer(parser.getAttributeValue(null, "id")));

      } else if (currentPerson != null) {

       if (name.equalsIgnoreCase("name")) {

        currentPerson.setName(parser.nextText());// 如果后面是Text节点,即返回它的值

       } else if (name.equalsIgnoreCase("age")) {

        currentPerson.setAge(new Short(parser.nextText()));

       }

      }

      break;

    case XmlPullParser.END_TAG://结束元素事件

      if (parser.getName().equalsIgnoreCase("person") && currentPerson != null) {

       persons.add(currentPerson);

       currentPerson = null;

      }

      break;

     }

     eventType = parser.next();

    }

    inputStream.close();

    return persons;

    } catch (Exception e) {

     e.printStackTrace();

    }

    return null;

   }

//将内容保存至XML文件

public static String writeXML(List<Person> persons, Writer writer){

     XmlSerializer serializer = Xml.newSerializer();

     try {

         serializer.setOutput(writer);

         serializer.startDocument("UTF-8", true);

       //第一个参数为命名空间,如果不使用命名空间,可以设置为null

         serializer.startTag("", "persons");

         for (Person person : persons){

             serializer.startTag("", "person");

             serializer.attribute("", "id", person.getId().toString());

             serializer.startTag("", "name");

             serializer.text(person.getName());

             serializer.endTag("", "name");

             serializer.startTag("", "age");

             serializer.text(person.getAge().toString());

             serializer.endTag("", "age");

             serializer.endTag("", "person");

         }

         serializer.endTag("", "persons");

         serializer.endDocument();

         return writer.toString();

     } catch (Exception e) {

         e.printStackTrace();

     }

     return null;

}

}

生成的person.xml如下:

<?xml version="1.0" encoding="UTF-8"?>

<persons>

<person id="23">

   <name>liming</name>

   <age>30</age>

</person>

<person id="20">

   <name>lili</name>

   <age>25</age>

</person>

</persons>

DOM解析XML文件

DOM解析XML文件时,会将XML文件的所有内容以文档树方式存放在内存中,然后允许您使用DOM API遍历XML树、检索所需的数据。使用DOM操作XML的代码看起来是比较直观的,并且在某些方面比基于SAX的实现更加简单。但是,因为DOM需要将XML文件的所有内容以文档树方式存放在内存中,所以内存的消耗比较大,特别对于运行Android的移动设备来说,因为设备的资源比较宝贵,所以建议还是采用SAX来解析XML文件,当然,如果XML文件的内容比较小采用DOM也是可行的。

 

public class DOMXmlReader {

public static List<Person> XMLReader(InputStream inStream)throws Exception{

   List<Person> persons=new ArrayList<Person>();

   DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();

   try{

    DocumentBuilder builder=factory.newDocumentBuilder();

    Document document= builder.parse(inStream);

    Element root=document.getDocumentElement();

    NodeList items=root.getElementsByTagName("person");//得到所有person节点

    for(int i=0;i<items.getLength();i++){

     Person person=new Person();

     Element personNode=(Element)items.item(i);

     person.setId(new Integer(personNode.getAttribute("id")));

      //获取person节点下的所有子节点(标签之间的空白节点和name/age元素)

     NodeList childsNodes = personNode.getChildNodes();

      for (int j = 0; j < childsNodes.getLength(); j++) {

      Node node = (Node) childsNodes.item(j);    //判断是否为元素类型

      if(node.getNodeType() == Node.ELEMENT_NODE){       

      Element childNode = (Element) node;

                                          //判断是否name元素

         if ("name".equals(childNode.getNodeName())) {

          //获取name元素下Text节点,然后从Text节点获取数据             person.setName(childNode.getFirstChild().getNodeValue());

         } else if ("age".equals(childNode.getNodeName())) {

      person.setAge(new Short(childNode.getFirstChild().getNodeValue()));

         }

      }

            }

        persons.add(person);

     }

     inStream.close();

    

   

   

   

   }catch(Exception e){

    e.printStackTrace();

   

   }

 

 

   return persons;

 

}

}

 

SAX是一种占用内存少且解析速度快的解析器,它采用的是事件启动,它不需要解析完整个文档,而是按照内容顺序 看文档某个部分是否符合xml语法,如果符合就触发相应的事件,所谓的事件就是些回调方法(callback),这些方法 定义在ContentHandler中,下面是其主要方法:

startDocument:当遇到文档的时候就触发这个事件 调用这个方法 可以在其中做些预处理工作。

 

startElement: (String namespaceURI,String localName,String qName,Attributes atts)当遇开始标签的时候就会触发这个方法。

endElement(String uri,String localName,String name):当遇到结束标签时触发这个事件,调用此法可以做些善后工作。

charachers(char [] ch,int start,int length):当遇到xml内容时触发这个方法,用new String(ch,start,length)可以接受内容。

下面是一个例子:

文件名称:person.xml

<?xml version="1.0" encoding="UTF-8"?> <persons> <person id="23"> <name>李明</name> <age>30</age> </person> <person id="20"> <name>李向梅</name> <age>25</age> </person> </persons>

public class SAXService {

public List<Person> personService(InputStream inStream)throws Exception{

   SAXParserFactory factory=SAXParserFactory.newInstance();

   SAXParser parser=factory.newSAXParser();

   PersonDefaultHandler handler=new PersonDefaultHandler();

   parser.parse(inStream, handler);

   inStream.close();

   return handler.getPersons();

}

private final class PersonDefaultHandler extends DefaultHandler{

   private List<Person> persons=null;

   private Person currentPerson;

   public List<Person> getPersons() {

    return persons;

   }

   public void setPersons(List<Person> persons) {

    this.persons = persons;

   }

   private String tagName=null;

   @Override

   public void characters(char[] ch, int start, int length)

     throws SAXException {

    if(tagName!=null){

     String data =new String(ch,start,length);

     if("name".equals(data)){

      currentPerson.setName(data);

    

     }else if("age".equals(data)){

      currentPerson.setAge(Short.parseShort(data));

    

     }

   

    }

   }

   @Override

   public void endElement(String uri, String localName, String qName)

     throws SAXException {

    if("person".equals(localName)){

   

     persons.add(currentPerson);

     currentPerson=null;

   

    }

    tagName=null;

  

   }

   @Override

   public void startDocument() throws SAXException {

    persons=new ArrayList<Person>();

   }

   @Override

   public void startElement(String uri, String localName, String qName,

     Attributes attr) throws SAXException {

    if("person".equals(localName)){

     currentPerson=new Person();

     currentPerson.setId(Integer.parseInt(attr.getValue("id")));

    

    }

    tagName=localName;

   }

 

}

}

下面是测试类:

public class PersonTest extends AndroidTestCase {

private static final String TAG="PersonTest";

public void testSAXService()throws Throwable{

   SAXService saxservice=new SAXService();

   InputStream inStream=this.getClass().getClassLoader().getResourceAsStream("person.xml");

   List <Person> persons=saxservice.personService(inStream);

   for(Person p:persons){

    Log.i(TAG,p.toString());

   }

}

}

本篇文章来源于 Linux公社网站(www.linuxidc.com)  原文链接:http://www.linuxidc.com/Linux/2010-11/29768p3.htm
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息