xml解析(读取xml,保存文件到xml)

前端之家收集整理的这篇文章主要介绍了xml解析(读取xml,保存文件到xml)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

在Android中,实现对XML的解析有三种方式,分别为DOM解析器,SAX解析器和PULL解析器。


  • DOM解析器

DOM是基于树形结构的节点或信息片段的集合,允许开发人员使用DOM API遍历XML树,检索所需数据。

分析该结构通常需要加载整个文档和构造树形结构,然后才可以检索和更新节点信息。

Android完全支持DOM解析。利用DOM中的对象,可以对XML文档进行读取,搜索修改添加删除等操作。


DOM的工作原理:使用DOM对XML文件进行操作时,首先要解析文件,将文件分为独立的元素,属性和注释等,

然后以节点树的形式在内存中对XML文件进行表示,就可以通过节点树访问文档的内容,并根据需要修改文档。


DOM实现时首先为XML文档的解析定义一组接口,解析器读入整个文档,然后构造一个驻留内存的树结构,

这样代码就可以使用DOM接口来操作整个树结构。


由于DOM在内存中以树形结构存放,因此检索和更新效率会更高。但是对于特别大的文档,解析和加载整个文档将会

很耗资源。当然,如果XML文件内容比较小,采用DOM是可行的。

常用的DOM接口和类:

Document: 该接口定义分析并创建DOM文档的一系列方法,它是文档树的根,是操作DOM的基础。

Element: 该接口继承Node接口,提供了获取修改XML元素名字和属性方法

Node: 该接口提供处理并获取节点和子节点值的方法

NodeList: 提供获得节点个数和当前节点的方法。这样就可以迭代地访问各节点。

DOMParser: 该类是Apache的Xerces中的DOM解析器类,可直接解析XML文件


示例:

    <?xml version="1.0" encoding="UTF-8"?>  
    <persons>  
        <person id="1">  
            <name>叶问</name>  
            <age>23</age>  
        </person>  
        <person id="2">  
            <name>李小龙</name>  
            <age>17</age>  
        </person>  
    </persons> 

public class DomXMLReader {

public static List<Person> readXML( InputStream inStream) {
        List<Person> persons = new ArrayList<Person>;
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        try {
             DocumentBuilder builer = factory.newDocumentBuilder();
             Document dom = builder.parse(inStream);
             Element root = dom.getDocumentElement();
            NodeList items = root.getElementsByTagName("person");
      //查找所有person节点
      for (int i = 0; i < items.getLength(); i++) {
           Person person = new Person();
           //得到第一个person节点
           Element personNode = (Element) items.item(i);
           //获取person节点的id属性值
           person.setId(new Integer(personNode.getAttribute("id")));
           //获取person节点下的所有子节点(标签之间的空白节点和name/age元素)
           NodeList childsNodes = personNode.getChildNodews();
           for( int j =0; j < childsNodes.getLength(); j++) {
            Node node = (Node) childsNodes.item(j);
            //判断是否为元素类型
            if( node.getNodeType() == Node.ELEMENT_NODE) {
                Element childNode = (Element) node;
                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解析器:

SAX解析器是一种基于事件的解析器,事件驱动的流式解析方式是,从文件的开始顺序解析到文档结束,不可暂停或倒退。

它的核心是事件处理模式,主要是围绕着事件源以及事件处理器来工作的。当事件源产生事件后,调用事件处理器相应的处理方法

一个事件就可以得到处理。在事件源调用事件处理器中特定方法的时候,还要传递给事件处理器相应事件的状态信息,这样事件处理器

才能根据提供的事件信息来决定自己的行为。


SAX解析器的优点是解析速度快,占用内存少。非常适合在Android移动设备中使用。

SAX的工作原理: 对文档进行顺序扫描,当扫描到文档(document)开始与结束,元素(element)开始与结束,文档(document)结束等

地方时通知事件处理函数,由事件处理函数做相应动作,然后继续同样的扫描直到文档结束。


在SAX接口中,事件源是org.xml.sax包中的XMLReader,它通过parser()方法来解析XML文档,并产生事件。

事件处理器是org.xml.sax包中ContentHandler,DTDHandler,ErrorHandler,以及EntityResolver这4个接口。

XMLReader通过相应事件处理器注册方法setXXXX()来完成的与ContentHandler,

以及EntivityResolver这4个接口的连接。

常用的SAX接口和类:

Attributes: 用于得到属性的个数,名字和值。

ContentHandler: 定义与文档本身关联的事件(例如,开始和结束标记)。大多数应用程序都注册这些事件。

DTDHandler: 定义与DTD关联的事件。它没有定义足够的事件来完整地报告DTD。如果需要对DTD进行语法分析,请使用可选的DeclHandler。

DeclHandler是SAX的扩展。不是所有的语法分析器都支持它。

EntityResolver:定义与装入实体关联的事件。只有少数几个应用程序注册这些事件。

ErrorHandler:定义错误事件。许多应用程序注册这些事件以便用它们自己的方式报错。

DefaultHandler:它提供了这些接LI的缺省实现。在大多数情况下,为应用程序扩展DefaultHandler并覆盖相关的方法要比直接实现一个接口更容易。



示例:

<?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 Person implements Serializable{
    private Integer id;
    private String name;
    private Short age;

    public Person() {
    }

    public Person(String name,Short age) {
        super();
        this.name = name;
        this.age = age;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Short getAge() {
        return age;
    }

    public void setAge(Short age) {
        this.age = age;
    }

}


public class XMLContenteHandler extends DefaultHandler {
 <span style="color:#000000;"> //临时变量,解决sax读取XML时不能读取换行符号后面的内容的问题;注意temp=""不能写成temp或temp=null,避免脏数据</span>
  private String temp="";
  private String preTag;
  private Person person;
  private List<Person> persons;

  public void startDocument() throws SAXException {
    persons = new ArrayList<Person>();
  }

  public void characters(char[] ch,int start,int length) throws SAXException {
    if(person != null) {
      String date = new String(ch,start,length);
      if("name".equals(preTag)){
       temp += date;
      } else if("age".equals(preTag)){
       temp += date;
      }
    }
  }

  public void startElement(String uri,String localName,String name,Attributes attributes) throws SAXException {
    if("person".equals(localName)){
      person = new Person();
      person.setId(attributes.getIndex("id"));
    }
    preTag = localName;
   }

   public void endElement( String uri,String name) throws SAXException {
    if(person != null && "name".equals(localName)) {
     person.setName(temp);
     temp="";
    } else if(person != null && "age".equals(localName)){
     person.setAge(new Short(temp));
     temp="";
    } else if(person != null && "person".equals(localName)) {
     persons.add(person);
     person = null;
    }
    preTag =null;
   }

   public List<person> getPersons() {
     return persons;
   }
}
public class SaxPersonService {
 // 业务层要对外抛出
 public static List<Person> readXML(InputStrean inStrean) throws Exception {
   
   SAXParserFactory spf = SAXParserFactory.newInstance();
   SAXParser saxParser = spf.newSAXParser();//创建解析器
   //设置解析器的相关特性,http://xnl.org/sax/features/namespaces = true;
   //表示开启命名空间特性
   //saxParser.setProperty("http://xnl.org/sax/features/namespaces",true);
   XMLContentHandler handler = new XMLContentHandler();
   saxParser.parse(inStream,handler);
   inStream.close();
   return handler.getPersons();
 }
}

public class SaxPersonServiceTest extends AndroidTestCase{
    private final String TAG = "SaxPersonServiceTest";
    public void testReadXML() throws Exception{
        //ljq.xml放在src目录下
        InputStream inputStream = SaxPersonServiceTest.class.getClassLoader().getResourceAsStream("ljq.xml");
        List<Person> persons = SaxPersonService.readXML(inputStream);
        for(Person person : persons){
           Log.i(TAG,person.getId() + " : " + person.getName() + " : " + person.getAge());
        }
    }
}

  • PULL解析器

PULL解析器的运行方式和SAX类似,都是基于事件的模式。不同的是,在PULL解析过程中返回的是数字,且我们需要自己获取产生的事件然后做相应的操作,而不像SAX那样由处理器触发一种事件的方法,执行我们的代码

PULL解析器小巧轻便,解析速度快,简单易用,非常适合在Android移动设备中使用,Android系统内部在解析各种XML时也是用PULL解析器,Android官方推荐开发者们使用Pull解析技术。Pull解析技术是第三方开发的开源技术,它同样可以应用于JavaSE开发。

PULL的工作原理:XML pull提供了开始元素和结束元素。当某个元素开始时,我们可以调用parser.nextText从XML文档中提取所有字符数据。当解释到一个文档结束时,自动生成EndDocument事件。


读取XML

XmlPullParser pullParser = Xml.newPullParser();

pullParser.setInput(xml,"UTF-8"); // 为破解器添加要解析的xml数据

int event = pullParser.getEventType(); //开始读取,获取事件返回值

pullParser.getName(); // 获取节点名称

pullParser.getAttributeValue(0); // 获取第一个属性的值

pullParser.nextText(); //获取标签之后的节点内容

event = pullParser.next(); // 解析器遇到结束标签不会自动向下解析,需要调用方法进行继续执行


保存文件到XML

public static void save(List<Person> persons,OutputStream outStream)
throws Exception,IllegalStateException,IOException {
XmlSerializer serializer = Xml.newSerializer();//获取XML写入信息的序列化对象
serializer.setOutput(outStream,"UTF-8");//设置要写入的OutputStream
serializer.startDocument("UTF-8",true);//设置文档标签

serializer.startTag(null,"persons");//设置开始标签,第一个参数为namespace
for (Person person : persons) {
serializer.startTag(null,"person");
serializer.attribute(null,"id",person.getId().toString());

serializer.startTag(null,"name");
serializer.text(person.getName());
serializer.endTag(null,"name");

serializer.startTag(null,"age");
serializer.text(person.getAge().toString());
serializer.endTag(null,"age");

serializer.endTag(null,"person");
}
serializer.endTag(null,"persons");
serializer.endDocument();
outStream.flush();
outStream.close();
}

猜你在找的XML相关文章