XML解析

来源:互联网 发布:淘宝网商贷款逾期了 编辑:程序博客网 时间:2024/05/17 07:22

1. XML总结

1.1. XML简介

XML : 可扩展的标记语言。(和HTML非常类似的)
- 可扩展的。
- 自定义的标签。

与HTML区别: XML传输数据,HTML是显示数据。

XML的版本: XML1.0(几乎都使用该版本) XML1.1(不向下兼容)

做什么用?=>描述有关系的数据

应用
1. 作为配置文件。
2. 可以在系统与系统之间进行数据的传输。
* webserivice soap XML封装数据
* json 和XML概念相似

1.2. XML基本语法

  • 文档声明(*

    • 写法:

1.3. XML约束

约束的分类
* DTD
* schema


hello.java
<猫/>

  • 格式良好的XML:遵循语法规范。
  • 有效的XML:有约束。

1.3.1. XML约束–DTD 约束

  • DTD的约束

    • 快速入门
    • 快速入门的步骤:

      • 需要出现哪些标签?
      • 在DTD的文件中编写元素
    <?xml version="1.0" encoding="UTF-8"?>    <!ELEMENT  班级 (学生+)>    <!ELEMENT  学生 (姓名,年龄,身高,体重)>    <!ELEMENT  姓名 (#PCDATA)>    <!ELEMENT  年龄 (#PCDATA)>    <!ELEMENT  身高 (#PCDATA)>    <!ELEMENT  体重 (#PCDATA)>    <!ATTLIST  班级        编号  ID #REQUIRED        年级  CDATA "三年级"        学校名 CDATA  #FIXED "西北工业大学"    >    <!ATTLIST  学生            编号  ID #REQUIRED            性别  (男|女)  #REQUIRED            癖好 CDATA  #IMPLIED    >

对应的 xml文件:

<?xml version="1.0" encoding="utf-8" ?><班级 编号="des3" 年级="大一" 学校='西工大' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"                          xmlns="http://www.example.org/student"                          xsi:schemaLocation=" http://www.example.org/student  student.xsd">    <学生 编号="d3" 性别="女" >        <姓名>阿娇</姓名>        <年龄>50</年龄>        <身高>150</身高>        <体重>40</体重>    </学生>    <学生 编号="df3" 性别="男">        <姓名>薛鹏</姓名>        <年龄>55</年龄>        <身高>175</身高>        <体重>70.32</体重>    </学生></班级>

1.3.2. XML约束–schema 约束

  • schema约束:

    • schema和DTD的对比(面试题):

      • schema符合XML的语法结构。
      • DOM、SAX 可以很好地解析schema文档。
      • schema对名称空间支持的好。
      • schem支持更多的数据类型,自定义的数据类型。
    • 预先定义元素和属性

    • schema的后缀名是.xsd
    • 必须只能有一个根节点,名称是schema。
  • 开发步骤

    • 开发schema的约束文档
    • schema文档声明

      <schema xmlns ="http://www.w3.org/2001/XMLSchema"
      targetNamespace="http://www.itcast.cn/1110"
      elementFormDefault="qualified"
      >
    • 引入W3C的名称

      • 在根节点上schema,使用属性xmlns (全称: xml namespace)
      • xmlns=”http://www.w3.org/2001/XMLSchema”
    • 起名:targetNamespace 目标名称空间(起名)

      • 值是任意的:”http://www.itcast.cn/1110” 一般为域名
        *
        • elementFormDefault
          qualified(使用):质量好的
          unqualified :质量不好的↑
    • 在XML文档中的–“根标签”—引入自己编写的schema文档

          <根标签 属性1="值1" 属性2="值2"            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"            xmlns="http://www.itcast.cn/1110"            xsi:schemaLocation="http://www.itcast.cn/1110 student.xsd"    >
      1. 引入W3C名称空间,我是实例文档。注意多了个 -instance
    • xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” (这里的xsi 是别名)

      1. 引入自己编写的schema的文档
    • xmlns=”http://www.itcast.cn/1110” xsd文档中的 targetNamespace 内容

    • 问题:元素上不能有相同的属性名称

      • 解决:起别名 :aa
      • 技巧:在下面出现标签的概率小起别名

        1. 引入自己编写的schema文档的地址
    • schemaLocation属性是W3C提供的,如果W3C名称空间要是有别名的话,先把别名写上。
      xsi:schemaLocation=”名称空间 schema文件的地址”

      • 名称空间的概念
        • 编写完schema文档,起唯一的名称空间。
        • 在编写XML文档,通过xmlns来引入名称空间。
      • 当标签为简单标签,没有属性时,简单文本的类型可直接在 主标签中定义

        表示标签名为 name,标签内内容为double 类型

      • 当标签有属性,不包含子标签时,也必须设置成complexType,
        且attribute属性必须在文本类型标签extension内,

        <element name="name">    <complexType>        <simpleContent>            <extension base="string">                <attribute name="salary" type="double" use="required"></attribute>  <!-- attribute位置-->            </extension>        </simpleContent>    </complexType></element>
      • 当标签有属性,且包含子标签时, 需要Sequence/choice/all标签,attribute标签必须在sequence结束标签和complexType标签之间,

          <element name="父标签">        <complexType>        <sequence>            <element name="子标签1"></element>            <element name="子标签2"></element>            <element name="子标签3"></element>        </sequence>       <attribute name="身高" ></attribute>     <!--  attribute位置-->        </complexType>    </element>
student.xsd<?xml version="1.0" encoding="UTF-8"?><schema xmlns="http://www.w3.org/2001/XMLSchema"    targetNamespace="http://www.example.org/student"    xmlns:tns="http://www.example.org/student" elementFormDefault="qualified">    <element name="班级" >        <complexType>            <sequence>                <element name="学生" maxOccurs="2">                    <complexType>                        <sequence>                            <element name="姓名" type="string"></element>                            <element name="年龄" type="int"></element>                            <element name="身高" type="double"> </element>                            <element name="体重" type="double"></element>                        </sequence>                        <attribute name="编号" type="string" use="required"> </attribute>                        <attribute name="性别" type="string" use="required"> </attribute>                    </complexType>                </element>            </sequence>            <attribute name="编号" type="string" use="required"></attribute>            <attribute name="年级" type="string" use= "required"></attribute>            <attribute name="学校" type="string" ></attribute>        </complexType>    </element></schema>

student.xml

<?xml version="1.0" encoding="utf-8" ?><班级 编号="des3" 年级="大一" 学校='西工大'                         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"                         xmlns="http://www.example.org/student"                         xsi:schemaLocation=" http://www.example.org/student  student.xsd">    <学生 编号="d3" 性别="女" >        <姓名>阿娇</姓名>        <年龄>50</年龄>        <身高>150</身高>        <体重>40</体重>    </学生>    <学生 编号="df3" 性别="男">        <姓名>薛鹏</姓名>        <年龄>55</年龄>        <身高>175</身高>        <体重>70.32</体重>    </学生></班级>

1.4. XML 解析(重点)

1.4.1. 解析方式简介

  • 常用的有两种?DOM和SAX
  • 区别:

    • DOM解析XML

      • 在内存中形成树状结构
      • 缺点:如果文档过大,容易产生内存溢出的问题。
      • 优点:方便做增删改的操作
    • SAX解析

      • 基于事件驱动,边读边解析
      • 优点:不会产生内存溢出问题。
      • 缺点:不能做增删改操作。

(DOM4J在内存生成树状结构,但是很少出现内存溢出,故一般使用 DOM4J 解析 xml)

1.4.1.1. DOM(JAXP Crimson解析器)

DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作。由于它是基于信息层次的,因而DOM被认为是基于树或基于对象的。DOM以及广义的基于树的处理具有几个优点。首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航,而不是像SAX那样是一次性的处理。DOM使用起来也要简单得多。

1.4.1.2. SAX

SAX处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。一般来说,SAX还比它的替代者DOM快许多。
  

选择DOM还是选择SAX? 对于需要自己编写代码来处理XML文档的开发人员来说, 选择DOM还是SAX解析模型是一个非常重要的设计决策。 DOM采用建立树形结构的方式访问XML文档,而SAX采用的事件模型。

各自的优点/缺点:
- DOM解析器把XML文档转化为一个包含其内容的树,并可以对树进行遍历。用DOM解析模型的优点是编程容易,开发人员只需要调用建树的指令,然后利用navigation APIs访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。然而由于使用DOM解析器的时候需要处理整个XML文档,所以对性能和内存的要求比较高,尤其是遇到很大的XML文件的时候。由于它的遍历能力,DOM解析器常用于XML文档需要频繁的改变的服务中。

  • SAX解析器采用了基于事件的模型,它在解析XML文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。SAX对内存的要求通常会比较低,因为它让开发人员自己来决定所要处理的tag。特别是当开发人员只需要处理文档中所包含的部分数据时,SAX这种扩展能力得到了更好的体现。但用SAX解析器的时候编码工作会比较困难,而且很难同时访问同一个文档中的多处不同数据。

1.4.1.3. JDOM

JDOM的目的是成为Java特定文档模型,它简化与XML的交互并且比使用DOM实现更快。由于是第一个Java特定模型,JDOM一直得到大力推广和促进。正在考虑通过“Java规范请求JSR-102”将它最终用作“Java标准扩展”。从2000年初就已经开始了JDOM开发。

JDOM与DOM主要有两方面不同。首先,JDOM仅使用具体类而不使用接口。这在某些方面简化了API,但是也限制了灵活性。第二,API大量使用了Collections类,简化了那些已经熟悉这些类的Java开发者的使用。

JDOM文档声明其目的是“使用20%(或更少)的精力解决80%(或更多)Java/XML问题”(根据学习曲线假定为20%)。JDOM对于大多数Java/XML应用程序来说当然是有用的,并且大多数开发者发现API比DOM容易理解得多。JDOM还包括对程序行为的相当广泛检查以防止用户做任何在XML中无意义的事。然而,它仍需要您充分理解XML以便做一些超出基本的工作(或者甚至理解某些情况下的错误)。这也许是比学习DOM或JDOM接口都更有意义的工作。

JDOM自身不包含解析器。它通常使用SAX2解析器来解析和验证输入XML文档(尽管它还可以将以前构造的DOM表示作为输入)。它包含一些转换器以将JDOM表示输出成SAX2事件流、DOM模型或XML文本文档。JDOM是在Apache许可证变体下发布的开放源码。

1.4.1.4. DOM4J(重点)

虽然DOM4J代表了完全独立的开发结果,但最初,它是JDOM的一种智能分支。它合并了许多超出基本XML文档表示的功能,包括集成的XPath支持、XML Schema支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项,它通过DOM4J API和标准DOM接口具有并行访问功能。从2000下半年开始,它就一直处于开发之中。

为支持所有这些功能,DOM4J使用接口和抽象基本类方法。DOM4J大量使用了API中的Collections类,但是在许多情况下,它还提供一些替代方法以允许更好的性能或更直接的编码方法。直接好处是,虽然DOM4J付出了更复杂的API的代价,但是它提供了比JDOM大得多的灵活性。

在添加灵活性、XPath集成和对大文档处理的目标时,DOM4J的目标与JDOM是一样的:针对Java开发者的易用性和直观操作。它还致力于成为比JDOM更完整的解决方案,实现在本质上处理所有Java/XML问题的目标。在完成该目标时,它比JDOM更少强调防止不正确的应用程序行为。

DOM4J是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的Java软件都在使用DOM4J来读写XML,特别值得一提的是连Sun的JAXM也在用DOM4J。

1.4.2. 解析

1.4.2.1. JAXP 下的 DOM 解析

解析
1. 获取 DocumentBuilderFactory(解析器工厂类)对象

    public static DocumentBuilderFactory newInstance();     获取 DocumentBuilderFactory 的新实例。
  1. 获取 DocumentBuilder(解析器)对象
    public abstract DocumentBuilder newDocumentBuilder() (虽然是抽象方法,但多态调用子类的实现方法)使用当前配置的参数创建一个新的 DocumentBuilder 实例。
  1. 解析XML文档
    public Document parse(String path)      解析XML文档,返回Document对象
  1. 根据需求获得NodeList 集合
    NodeList nodeList = document.getElementsByTagName("作者");
  1. 遍历NodeList集合 获取每个Node内的内容
    NodeList:        Node item(int index);  根据下标获取NodeList集合中的Node对象    Node:        String getTextContent();  获取Node对象(标签)中的文本内容    for(int i=0;i<nodeList.getLength();i++){        Node node = nodeList.item(i);        System.out.println(node.getTextContent());    }

示例:

    解析XML(Document parse(String uri) )    // 获取解析器工厂类    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();    // 获取解析器对象    DocumentBuilder builder = factory.newDocumentBuilder();    // 解析XML的文档,返回document对象    Document document = builder.parse("src/book2.xml");    // 获取作者元素对象的集合,返回NodeList,注意返回的是NodeList(ELement的父类)而不是Element    NodeList nodeList = document.getElementsByTagName("作者");    // 循环遍历,拿到每一个作者,打印文本的内容,getTextContent()    for(int i=0;i<nodeList.getLength();i++){        Node node = nodeList.item(i);        System.out.println(node.getTextContent());    }
    //获取标签的属性值    Document doc = JaxpDomutil.getDocument("src/book1.xml");    Node node = doc.getElementsByTagName("书").item(0);    NamedNodeMap attMap = node.getAttributes();            注意这里返回的是NamedNodeMap子类对象(实际上是属性集合)    System.out.println("--------------------");    System.out.println(attMap.getLength());    for(int i=0;i<attMap.getLength();i++){        Node att=attMap.item(i);                  node ---content        System.out.println(att.getTextContent());    }
    //递归得到 Node 中的所有节点名称(前序遍历)    public static void getNodeName(Node node){        if(node.getNodeType() == Node.ELEMENT_NODE){            System.out.println(node.getNodeName());        }        NodeList nodeList = node.getChildNodes();        for(int i=0;i<nodeList.getLength();i++){            Node child = nodeList.item(i);            getNodeName(child);        }    }

回写
* 获取回写的工厂类
* 获取回写对象
* 调用回写的方法进行回写。

修改 document对象中的内容之后进行回写

    // 创建回写类的工厂    TransformerFactory transformerFactory =  TransformerFactory.newInstance();    // 获取回写类    Transformer transformer = transformerFactory.newTransformer();    // 调用回写的方法    transformer.transform(new DOMSource(document), new StreamResult("src/book2.xml"));
//将获取Document对象和 回写封装到方法中public class JaxpDomutil {    public static Document getDocument(String path) throws Exception{    DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();    DocumentBuilder builder = builderFactory.newDocumentBuilder();    return builder.parse(path);    }    public static void writeXML(Document doc,String path) throws Exception{    TransformerFactory transformerFactory = TransformerFactory.newInstance();    Transformer transformer = transformerFactory.newTransformer();    transformer.transform(new DOMSource(doc), new StreamResult(path));    }    //  在指定的节点之前添加子节点    public static void InsertBefore(Node newNode,Node refNode){        Node parentNode = refNode.getParentNode();        parentNode.insertBefore(newNode, refNode);    }}

1.4.2.2. JAXP 下的 SAX 解析

SAX的解析原理:

解析器采用SAX方式在解析某个XML文档时,它只要解析到XML文档的一个组成部分(边读边解析)
都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,
会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。

事件处理器由程序员编写,程序员通过事件处理器中方法的参数,
就可以很轻松地得到sax解析器解析到的数据,从而可以决定如何对数据进行处理。

解析过程
1. 获取解析器的工厂

    SAXParserFactory saxParseFactory = SAXParserFactory.newInstance();
  1. 获取解析器对象
    SAXParser saxParser = saxParseFactory.newSAXParser();
  1. 解析XML(XML的文件的地址,事件处理器)
    saxParser.parse(path,new MyHandler());   // 其中MyHandler() 继承自DefaultHandler()
  • 事件处理器(DefaultHandler)?
    自己编写的类MyHandler(),需要继承DefalutHandler类,重写三个方法。

    • startElement(qName) 开始标签名
    • characters(char[] ch,int start,int length) 标签内部文本内容
    • endElement(qName) 结束标签名

    通过传进来的参数qName、char[] 、qName 获取开始标签内容、文本内容、结束标签内容

1.4.3. DOM4j

  • DOM4J的解析(必须会,企业中用的多)
    • 先下载DOM4J相应的jar包。导入工程中,才能使用。
    • 把dom4j-1.6.1.jar导入到工程中。
    • WEB项目:复制dom4j-1.6.1.jar到 WebRoot – WEB-INF – lib里面。就ok。
    • Java项目:右键工程项目,选择Build Path

解析过程
1. 获取解析器对象

    SAXReader saxReader=new SAXReader();
  1. 解析获取Document对象
    Document doc = saxReader.read("src/book1.xml");
  1. 获取文档根结点
    Element root = doc.getRootElement();

DOM4j中,获得Document对象的方式有三种:

  1. 读取XML文件,获得document对象
    SAXReader reader = new SAXReader();    Document  document = reader.read(new File("input.xml"));
  1. 解析XML形式的文本,得到document对象.
    String text = "<members></members>";    Document document = DocumentHelper.parseText(text);
  1. 主动创建document对象.
    Document document = DocumentHelper.createDocument();  //创建根节点    Element root = document.addElement("members");

节点方法
1. 获取文档的根节点.

    Element root = document.getRootElement();
  1. 取得某个节点的子节点.
    Element element=root.element("书名");
  1. 取得节点的文本内容
    String text=node.getText();
  1. 取得某节点下所有名为“member”的子节点,并进行遍历.
    List nodes = rootElm.elements("member");         -->获取所有子元素结点    for (Iterator it = nodes.iterator(); it.hasNext();) {                Element elm = (Element) it.next();            // do something    }
  1. 对某节点下的所有子节点进行遍历.
    for(Iterator it=root.elementIterator();it.hasNext();){            Element element = (Element) it.next();        // do something??    }
  1. 在某节点下添加子节点.
    Element ageElm = newMemberElm.addElement("age");    (可通过父结点root添加        List<Element> eles = root.elements();        Element newEle=DocumentHelper.createElement("age");        newEle.setText("16");        eles.add(1,newEle);         -->插入子节点集合中的1位置        )
  1. 设置节点文字.
    element.setText("29");
  1. 删除某节点.
    parentElm.remove(childElm);     //childElm是待删除的节点,parentElm是其父节点
  1. 添加一个CDATA节点.
    Element contentElm = infoElm.addElement("content");    contentElm.addCDATA(diary.getContent());

属性方法:

        attribute.getQualifiedName()       getValue()/getText()                            属性名                   属性值
  1. 取得某节点下的某属性
    Element root=document.getRootElement();     //属性名name    Attribute attribute=root.attribute("size");
  1. 取得属性的文字
    String text=attribute.getText();
  1. 删除某属性
    Attribute attribute=root.attribute("size");    root.remove(attribute);
  1. 遍历某节点的所有属性
    Element root=document.getRootElement();    方法一:推荐    for(int i=0;i<root.attributeCount();i++){        Attribute attribute = root.attribute(i);        System.out.println(attribute.getQualifiedName()+"\""+attribute.getValue+"\"");    }    方法二:    for(Iterator it=root.attributeIterator();it.hasNext();){        Attribute attribute = (Attribute) it.next();        String text=attribute.getText();        System.out.println(text);    }
  1. 设置某节点的属性和文字.
    newMemberElm.addAttribute("name", "sitinspring");
  1. 设置属性的文字
    Attribute attribute=root.attribute("name");    ---> 获取属性名为 name 的属性对象    attribute.setText("sitinspring");              ---> 设置属性值

将文档写入XML
1. 文档中全为英文,不设置编码,直接写入的形式.

XMLWriter writer = new XMLWriter(new  FileWriter("output.xml"));writer.write(document);writer.close();
  1. 文档中含有中文,设置编码格式写入的形式.
    OutputFormat format = OutputFormat.createPrettyPrint();       // 指定XML编码    format.setEncoding("GBK");    XMLWriter writer = new XMLWriter(newFileWriter("output.xml"),format);    writer.write(document);    writer.close();

字符串与XML的转换

  1. 将字符串转化为XML
    String text = "<members> <member>sitinspring</member></members>";    Document document = DocumentHelper.parseText(text);

2.将文档或节点的XML转化为字符串.

    SAXReader reader = new SAXReader();    Document  document = reader.read(new File("input.xml"));    String docXmlText=document.asXML();      --> 将XML文档转换成XML格式的字符串    Element root=document.getRootElement();    String rootXmlText=root.asXML();          --> 将根结点转换成XML格式的字符串    Element memberElm=root.element("member");    String memberXmlText=memberElm.asXML();  --> 将元素结点转换成XML格式的字符串
  • DOM4J对XPATH的支持

    • 导入包。jaxen-1.1-beta-6.jar。
    • 怎么使用?
      selectNodes(“/AAA”) 返回集合
      selectSingleNode() 一个Node对象

    • 参数就是xpath的语法
      / 考虑层级关系 / / 不考虑层级关系

      /AAA/BBB            获取BBB的节点//AAA/BBB         A不考虑层级,B考虑层级/ /BBB              无论层级关系,找到BBB的节点*                   代表是所有/AAA/BBB[1]     找到BBB的第一个    /AAA/BBB[last()]   最后一个上面这种只能用单斜线 不能用双斜线@                   属性/*/*/*/BBB  代表三层标签下的 BBB标签

将文档写入XML
1.文档中全为英文,不设置编码,直接写入的形式.

    XMLWriter writer = new XMLWriter(new  FileWriter("output.xml"));    writer.write(document);    writer.close();

2.文档中含有中文,设置编码格式写入的形式.

    OutputFormat format = OutputFormat.createPrettyPrint();// 指定XML编码????? ????????????     format.setEncoding("GBK");    XMLWriter writer = new XMLWriter(newFileWriter("output.xml"),format);    writer.write(document);    writer.close();

1.4.4. Pull解析

与Sax一样.都属于事件驱动的解析方式.
相比Sax解析过程更加灵活.
sax一旦开始解析就是从头读到尾.不解析完整个文档不会停
pull解析较为灵活.是以事件为单位.手动向下继续. 如果获得到我们要找的内容. 可以停止继续解析.

缺点:只能进行查询,不能做增删改

    public static List<Student> parseXML(InputStream is) throws Exception{        //1:创建解析器工厂        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();        //2:使用工厂获得解析器        XmlPullParser parser = factory.newPullParser();        //3: 使用解析器读取XML流        parser.setInput(is, "UTF-8");        //4: 获得当前事件的状态        int type = parser.getEventType();        List<Student> list =null;        Student stu = null;        //5:判断当前事件状态        while(type!=XmlPullParser.END_DOCUMENT){            switch(type){                case XmlPullParser.START_TAG:                    if("students".equals(parser.getName())){                        list = new ArrayList<Student>();                    }else if("student".equals(parser.getName())){                        stu = new Student();                    }else if("name".equals(parser.getName())){                        String name = parser.nextText();                        stu.setName(name);                    }else if("age".equals(parser.getName())){                        int age = Integer.parseInt(parser.nextText());                        stu.setAge(age);                    }else if("height".equals(parser.getName())){                        double height = Double.parseDouble(parser.nextText());                        stu.setHeight(height);                    }                    break;                case XmlPullParser.END_TAG:                    if("student".equals(parser.getName())){                        list.add(stu);                        stu = null;                    }                    break;                default:                    break;            }            //让解析器向下解析一行,并返回改行的事件常量            type = parser.next();        }        return list;    }
原创粉丝点击