本章内容我们学习 如何使用DOM方式去解析和生成XML

一、DOM解析XML

    DOM是基于树形结构的的节点或信息片段的集合,允许开发人员使用DOM API遍历XML树、检索所需数据。分析该结构通常需要加载整个文档和构造树形结构,然后才可以检索和更新节点信息。Android完全支持DOM 解析。利用DOM中的对象,可以对XML文档进行读取、搜索、修改、添加和删除等操作。

    DOM的工作原理:使用DOM对XML文件进行操作时,首先要解析文件,将文件分为独立的元素、属性和注释等,然后以节点树的形式在内存中对XML文件进行表示,就可以通过节点树访问文档的内容,并根据需要修改文档——这就是DOM的工作原理。

DOM实现时首先为XML文档的解析定义一组接口,解析器读入整个文档,然后构造一个驻留内存的树结构,这样代码就可以使用DOM接口来操作整个树结构。

DOM的优点

    由于DOM在内存中以树形结构存放,因此检索和更新效率会更高。

DOM的缺点

    但是对于特别大的文档,解析和加载整个文档将会很耗资源。 当然,如果XML文件的内容比较小,采用DOM是可行的。

 常用的DoM接口和类:

Document 该接口定义分析并创建DOM文档的一系列方法,它是文档树的根,是操作DOM的基础。 
Element 该接口继承Node接口,提供了获取、修改XML元素名字和属性的方法。
Node 该接口提供处理并获取节点和子节点值的方法。
NodeList 提供获得节点个数和当前节点的方法。这样就可以迭代地访问各个节点。
DOMParser 该类是Apache的Xerces中的DOM解析器类,可直接解析XML文件。

 

下面是解析的流程

   
   
   
   
  1. //      *首先利用DocumentBuilderFactory创建一个DocumentBuilderFactory实例 
  2. //      *然后利用DocumentBuilderFactory创建DocumentBuilder 
  3. // 
  4. //      *然后加载XML文档(Document), 
  5. //      * 然后获取文档的根结点(Element), 
  6. //      * 然后获取根结点中所有子节点的列表(NodeList), 
  7. //      * 然后使用再获取子节点列表中的需要读取的结点。 

讲了这么多了  接下来写个例子来解析下吧

说到解析 肯定要有xml文件啦    我们把xml文件放在assets目录下  文件内容为

   
   
   
   
  1. xml version="1.0" encoding="UTF-8"?> 
  2. <persons> 
  3.     <person id="23"> 
  4.         <name>李磊name> 
  5.         <age>30age> 
  6.     person> 
  7.     <person id="20"> 
  8.         <name>韩梅梅name> 
  9.         <age>25age> 
  10.     person> 
  11. persons> 

新建一个Values类  用来存储数据

   
   
   
   
  1. package com.example.demo; 
  2.  
  3. import java.io.Serializable; 
  4.  
  5. public class Values implements Serializable { 
  6.  
  7.     /** 
  8.      *  
  9.      */ 
  10.     private static final long serialVersionUID = 1L; 
  11.     private String _id; 
  12.     private String _name; 
  13.     private String _age; 
  14.  
  15.     public String get_id() { 
  16.         return _id; 
  17.     } 
  18.  
  19.     public void set_id(String _id) { 
  20.         this._id = _id; 
  21.     } 
  22.  
  23.     public String get_name() { 
  24.         return _name; 
  25.     } 
  26.  
  27.     public void set_name(String _name) { 
  28.         this._name = _name; 
  29.     } 
  30.  
  31.     public String get_age() { 
  32.         return _age; 
  33.     } 
  34.  
  35.     public void set_age(String _age) { 
  36.         this._age = _age; 
  37.     } 

接下来编写解析的方法  注视都在下面的代码中写出

   
   
   
   
  1. public void getDomXML(InputStream is){ 
  2.          
  3.         //创建list 用于保存读取的内容 
  4.         List list  = new ArrayList(); 
  5.          
  6.         //得到DocumentBuilderFactory对象  由该对象可以得到 DocumentBuilder 对象 
  7.         DocumentBuilderFactory builderFactory  = DocumentBuilderFactory.newInstance(); 
  8.          
  9.         try { 
  10.             //得到DocumentBuilder对象  
  11.             DocumentBuilder builder = builderFactory.newDocumentBuilder(); 
  12.             //得到代表整个xml的Document对象 
  13.             Document document = builder.parse(is); 
  14.             //得到根节点 
  15.             Element element = document.getDocumentElement(); 
  16.             //获取根节点中的所有的person节点 
  17.             NodeList nodeList = element.getElementsByTagName("person"); 
  18.             //获取长度 
  19.             int length = nodeList.getLength(); 
  20.              
  21.             for (int i = 0; i < length; i++) { 
  22.                 Values values = new Values(); 
  23.                 Element element2 = (Element) nodeList.item(i); 
  24.                 values.set_id(element2.getAttribute("id")); 
  25.                 //获取节点中的子节点list 
  26.                 NodeList childnodes = element2.getChildNodes(); 
  27.                 //遍历子节点 
  28.                 for (int j = 0; j < childnodes.getLength(); j++) { 
  29.                     //获取当前节点 
  30.                     Node node  = childnodes.item(j); 
  31.                     //如果当前节点是元素节点的话  getNodeType()获取节点类型 
  32.                     if(node.getNodeType()  == Node.ELEMENT_NODE){ 
  33.                         //判断节点名称是否是 age 
  34.                         if(node.getNodeName().equals("age")){ 
  35.                             //获取节点值 
  36.                             values.set_age(node.getFirstChild().getNodeValue()); 
  37.                         } 
  38.                         else if(node.getNodeName().equals("name")){ 
  39.                             values.set_name(node.getFirstChild().getNodeValue()); 
  40.                         } 
  41.                     } 
  42.                 } 
  43.                 list.add(values); 
  44.             } 
  45.         } catch (Exception e) { 
  46.             // TODO: handle exception  
  47.             System.err.println(e.toString()); 
  48.             return
  49.         } 
  50.          
  51.         //下面的代码将解析的内容打印出来 
  52.         StringBuffer buffer = new StringBuffer(); 
  53.         int length = list.size(); 
  54.         for (int i = 0; i < length; i++) { 
  55.             Values values = list.get(i); 
  56.             if(values.get_id()!=null
  57.                 buffer.append(values.get_id()+"\t"); 
  58.              
  59.             if(values.get_name()!=null
  60.                 buffer.append(values.get_name()+"\t"); 
  61.          
  62.             if(values.get_age()!=null
  63.                 buffer.append(values.get_age()+"\n"); 
  64.              
  65.         } 
  66.          
  67.         Toast.makeText(activity, buffer, Toast.LENGTH_LONG).show(); 
  68.          
  69.     } 

运行方法 得到如下图的内容  说明解析成功

【Android网络开发の1】XML之DOM方式 解析和生成XML文件_第1张图片

如果xml来源不是文件  而是String字符串?  应该怎么做? 就是把xml字符串转换为InputStream

   
   
   
   
  1. String xmlString = ""  
  2.                     + "      李磊     30   "  
  3.                     +       韩梅梅        25   ";  
  4. //转换为inputStream类型  
  5. InputStream is = new ByteArrayInputStream(xmlString.getBytes("UTF-8"));  

 


 二、DOM生成XML

写完解析 我们来写生成

也是使用上面的数据 

下面是生成的代码,注释都写了

   
   
   
   
  1. /** 
  2.  * 生成xml 
  3.  * */ 
  4. public void createXML() { 
  5.     // TODO Auto-generated method stub 
  6.     // 模拟数据 
  7.     List list = createValues(); 
  8.  
  9.     DocumentBuilderFactory builderFactory = DocumentBuilderFactory 
  10.             .newInstance(); 
  11.     try { 
  12.  
  13.         DocumentBuilder builder = builderFactory.newDocumentBuilder(); 
  14.  
  15.         Document document = builder.newDocument(); 
  16.         // 建立根节点 person 
  17.         Element element = document.createElement("persons"); 
  18.         // 添加到document 
  19.         document.appendChild(element); 
  20.  
  21.         for (int i = 0; i < list.size(); i++) { 
  22.             Values values = list.get(i); 
  23.             // 建立节点person 
  24.             Element person = document.createElement("person"); 
  25.             // 添加id属性 
  26.             person.setAttribute("id", values.get_id()); 
  27.             // 把节点添加到document 
  28.             element.appendChild(person); 
  29.  
  30.             // 添加name元素 
  31.             Element name = document.createElement("name"); 
  32.             //给name元素设置值 
  33.             name.setTextContent(values.get_name()); 
  34.             //添加到person节点 
  35.             person.appendChild(name); 
  36.  
  37.             // 添加age元素 
  38.             Element age = document.createElement("age"); 
  39.             age.setTextContent(values.get_age()); 
  40.             person.appendChild(age); 
  41.         } 
  42.          
  43.         //设置输出结果 
  44.         DOMSource domSource = new DOMSource(document); 
  45.         StringWriter writer = new StringWriter(); 
  46.         StreamResult result = new StreamResult(writer); 
  47.         TransformerFactory factory = TransformerFactory.newInstance(); 
  48.         Transformer transformer = factory.newTransformer(); 
  49.         //开始把Document映射到result  
  50.         transformer.transform(domSource, result); 
  51.          
  52.         Toast.makeText(activity, writer.toString(), Toast.LENGTH_LONG).show(); 
  53.     } catch (Exception e) { 
  54.         // TODO: handle exception 
  55.         e.printStackTrace(); 
  56.     } 
  57.  

运行方法之后  如果显示下面的图,那就说明生成成功了

【Android网络开发の1】XML之DOM方式 解析和生成XML文件_第2张图片

下面给出测试代码生成的方法

   
   
   
   
  1. private List createValues() { 
  2.         // 模拟数据 
  3.         List list = new ArrayList(); 
  4.         Values values = new Values(); 
  5.         values.set_id("23"); 
  6.         values.set_name("李磊"); 
  7.         values.set_age("30"); 
  8.         list.add(values); 
  9.  
  10.         values = new Values(); 
  11.         values.set_id("20"); 
  12.         values.set_name("韩梅梅"); 
  13.         values.set_age("25"); 
  14.         list.add(values); 
  15.  
  16.         return list; 
  17.     } 

概括流程:

   
   
   
   
  1. //创建Document  
  2. //  ↓↓ 
  3. //创建主节点 添加到document  
  4. //  ↓↓ 
  5. //创建节点   添加到主节点  
  6. //  ↓↓ 
  7. //创建元素   设置值  添加到节点  
  8. //  ↓↓ 
  9. //生成成功  

DOM方式的解析和生成已经讲完了   

下面一章将讲解SAX的解析和生成