Android中XML解析

来源:互联网 发布:电商erp软件 编辑:程序博客网 时间:2024/04/25 14:52
 

1       Xml解析

1.1     Dom解析

1.1.1  Dom解析原理

Dom解析,是把一个xml文件全部读入到内存之中进行解析的,利用JAVA自带的函数parse进行解析,在调用parse方法后,xml的解析就已经完成,而xml文件就以节点树的形式存储在了Document之中。我们只需要根据自己的需要在Document之中去访问节点,获取文本即可。

由于Dom解析需要把文本全部读入内存之中,因此会消耗大量的内存,但是Dom解析比较方便去访问各节点,并且也能够从全局上看出整个xml父子关系以及内部结构。在Android开发过程中不推荐使用,除非xml十分小。

1.1.2  Dom具体实现方法

Dom解析是按照W3C标准所制定的,解析过程:

1、  以文件流的方式读取xml文件。

inputStream = this.getClass().getClassLoader().getResourceAsStream("beauties.xml");

在此要十分注意,beauties.xml必须放在src目录下,不能是其子目录。

2、  定义一个文档构建工厂。

Eg:DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

3、  定义一个文件构建器

Eg:DocumentBuilder builder = factory.newDocumentBuilder();

4、  定义一个文档用来存放解析后的文档树。

Eg:Document document = builder.parse(inputStream);

这时对xml文档解析已经完成,现在就可以从document这个变量中提取我们所需要的节点以及节点的属性等。

5、 Element root = document.getDocumentElement();可以获得此节点树的根节点,在由此根据此根节点可以一步一步访问我们所需的节点中的Text节点。

6、 在获得我们需要的文本内容前,需要对节点标签名字和类型进行判断。

getNodeName获得标签名字,getNodeType获得节点确切类型,

getNodeValue返回节点内容,如果是文本节点返回文本内容,否则返回null

getTextContent返回当前节点以及其子代节点的文本字符串

解析的样例代码:try {

           DocumentBuilderFactory factory = DocumentBuilderFactory

                  .newInstance();

           DocumentBuilder builder = factory.newDocumentBuilder();

           Document document = builder.parse(inputStream);

           // 获取根节点

           Element root = document.getDocumentElement();

 

           parse(root);

 

           for (Beauty b : beautyList) {

              result += b.toString();

           }

 

           TextView textView = (TextView) findViewById(R.id.textView);

           textView.setText(result);

 

       } catch (Exception e) {

           e.printStackTrace();

       }

private void parse(Element element) {

       NodeList nodelist = element.getChildNodes();

       int size = nodelist.getLength();

       for (int i = 0; i < size; i++) {

           Node element2 = (Node) nodelist.item(i);

           String tagName = element2.getNodeName();

           if (tagName.equals("beauty")

                  && element2.getNodeType() == Document.ELEMENT_NODE) {

              beauty = new Beauty();

              if (element2.getNodeType() == Document.ELEMENT_NODE) {

                  parse((Element) element2);//递归进行访问

              }

              beautyList.add(beauty);

 

           }

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

              String name = element2.getTextContent();

              beauty.setName(name);

 

           }

           if (tagName.equals("age")) {

              String age = element2.getTextContent();

              beauty.setAge(age);

 

           }

 

       }

    }

1.2     Pull解析

1.2.1  Pull解析原理

Pull解析是Android自带的一种解析方式。使用的是事件触发的方式,他不需要把所有xml文档都读入进内存之中,而事件的类型是以整数的形式表示。在使用Pull解析时可以随时终止解析,因此当我们找到我们所需内容后,则可以终止解析。由于Pull解析是Android自带的一种解析方式,并且不会把所有xml文件的内容读入内存,达到了对内存的较低消耗,所以面对手机客户端的应用开发,这是一种十分推崇的方式。对于效率优先的这种方式也有自己的不足,就是不能很好的了解xml文件的内部结构。

1.2.2  Pull解析实现方法

1、  以文件流的方式读取xml文件。

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

注意:person.xml文件也必须存在src目录下,不能是其子目录。

2、  获取一个XmlPullParser

XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance();

XmlPullParser parser = xmlPullParserFactory.newPullParser();

3、  设置输入流编码方式

parser.setInput(inputStream, "UTF-8");此处以UTF-8为例。

4、  获取当前事件类型

int eventType = parser.getEventType();

具有的类型有:XmlPullParser.END_DOCUMENT,XmlPullParser.START_TAG,XmlPullParser.END_TAG,XmlPullParser.START_DOCUMENT等事件类型。

5、  根据其事件类型进行不同的处理,

getAttributeValue获取属性值,getName获取元素节点名称。

parser.next()触发下一个 事件。

样例代码:其中解析出的每一项都并列的显示在列表之中。

try{

        //以流的形式获取SRC目录下的xml文件(此文件父亲文件夹必须是SRC)

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

        //获取一个XmlPullParser

        XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance();

        XmlPullParser parser = xmlPullParserFactory.newPullParser();

        //设置输入流已经编码方式

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

        //获取当前事件类型

        int eventType = parser.getEventType();

        int i = -1;

        String[] data = new String[20];

        Person person = null;

        while(XmlPullParser.END_DOCUMENT!=eventType){

             String nodeName = parser.getName();

             switch(eventType){

             case XmlPullParser.START_TAG:

                if(nodeName.equals("s")||nodeName.equals("c")){

                    i++;

                    data[i] = parser.getAttributeValue(0)+"     "+parser.getAttributeValue(1);

                }

                break;

             case XmlPullParser.END_TAG:

                if(nodeName.equals("s")||nodeName.equals("c")&&person!=null){

                    persons.add(person);

                }

                break;

             default :

                    break;

             }

              //手动触发下一个事件

             eventType = parser.next();

        }

        for (; i < 20; i++) {

                data[i] = "列表项" + i;

            }

        ArrayAdapter<String> arrayAdapter = new  ArrayAdapter<String>(this, R.layout.main, data);

        this.setListAdapter(arrayAdapter);

        }

        catch (Exception e) {  

        System.out.println("-------->出现异常");

                   e.printStackTrace();  

        }

1.3     Sax解析

1.3.1  Sax解析原理

顺序的对文档进行扫描,当扫描到文档(Document)开始与结束、元素(Element)开始与结束等地方时通知事件处理函数,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束。

在解析工程中主要产生以下事件:

start document,start element,characters,end element,end document

与之相对应的有一下几种方式:

Void startDocument()       //文档开始处理方式

Void endDocument()       //文档结束处理方式

Void startElement(String uri,String localName,String qName,Attibutes atts)   //元素开始处理方式,localName是不带前缀的名字,qName是带前缀的名字。

Void endElement(String uri,String localName,String qName)        //元素结束处理方式

Void character(char[] ch,int start int length)                    

1.3.2  Sax实现方法

1、  以文件流的方式读取文件,同pull解析。

2、  写一个类继承DefaulterHandler,实现自己的事件处理方法。

3、  获取一个Sax解析器

SAXParserFactory factory = SAXParserFactory.newInstance();

SAXParser parser = factory.newSAXParser();

4、  开始解析

具体代码实现,由于SAX解析原理和Pull解析很相似,不同在于,SAX解析器,解析过程是自动的,不能人工控制,而Pull可以主动的去获取事件,所以Pull可以随时在获取了需要的条件后结束解析。所以我没有现实Sax解析的具体代码。