本章內容我們學習 如何使用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文件。 |
下面是解析的流程
- // *首先利用DocumentBuilderFactory創建一個DocumentBuilderFactory實例
- // *然後利用DocumentBuilderFactory創建DocumentBuilder
- //
- // *然後加載XML文檔(Document),
- // * 然後獲取文檔的根結點(Element),
- // * 然後獲取根結點中所有子節點的列表(NodeList),
- // * 然後使用再獲取子節點列表中的需要讀取的結點。
講了這麼多了 接下來寫個例子來解析下吧
說到解析 肯定要有xml文件啦 我們把xml文件放在assets目錄下 文件內容爲
- <?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>
新建一個Values類 用來存儲數據
- package com.example.demo;
- import java.io.Serializable;
- public class Values implements Serializable {
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- private String _id;
- private String _name;
- private String _age;
- public String get_id() {
- return _id;
- }
- public void set_id(String _id) {
- this._id = _id;
- }
- public String get_name() {
- return _name;
- }
- public void set_name(String _name) {
- this._name = _name;
- }
- public String get_age() {
- return _age;
- }
- public void set_age(String _age) {
- this._age = _age;
- }
- }
接下來編寫解析的方法 注視都在下面的代碼中寫出
- public void getDomXML(InputStream is){
- //創建list 用於保存讀取的內容
- List<Values> list = new ArrayList<Values>();
- //得到DocumentBuilderFactory對象 由該對象可以得到 DocumentBuilder 對象
- DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
- try {
- //得到DocumentBuilder對象
- DocumentBuilder builder = builderFactory.newDocumentBuilder();
- //得到代表整個xml的Document對象
- Document document = builder.parse(is);
- //得到根節點
- Element element = document.getDocumentElement();
- //獲取根節點中的所有的person節點
- NodeList nodeList = element.getElementsByTagName("person");
- //獲取長度
- int length = nodeList.getLength();
- for (int i = 0; i < length; i++) {
- Values values = new Values();
- Element element2 = (Element) nodeList.item(i);
- values.set_id(element2.getAttribute("id"));
- //獲取節點中的子節點list
- NodeList childnodes = element2.getChildNodes();
- //遍歷子節點
- for (int j = 0; j < childnodes.getLength(); j++) {
- //獲取當前節點
- Node node = childnodes.item(j);
- //如果當前節點是元素節點的話 getNodeType()獲取節點類型
- if(node.getNodeType() == Node.ELEMENT_NODE){
- //判斷節點名稱是否是 age
- if(node.getNodeName().equals("age")){
- //獲取節點值
- values.set_age(node.getFirstChild().getNodeValue());
- }
- else if(node.getNodeName().equals("name")){
- values.set_name(node.getFirstChild().getNodeValue());
- }
- }
- }
- list.add(values);
- }
- } catch (Exception e) {
- // TODO: handle exception
- System.err.println(e.toString());
- return;
- }
- //下面的代碼將解析的內容打印出來
- StringBuffer buffer = new StringBuffer();
- int length = list.size();
- for (int i = 0; i < length; i++) {
- Values values = list.get(i);
- if(values.get_id()!=null)
- buffer.append(values.get_id()+"\t");
- if(values.get_name()!=null)
- buffer.append(values.get_name()+"\t");
- if(values.get_age()!=null)
- buffer.append(values.get_age()+"\n");
- }
- Toast.makeText(activity, buffer, Toast.LENGTH_LONG).show();
- }
運行方法 得到如下圖的內容 說明解析成功
如果xml來源不是文件 而是String字符串? 應該怎麼做? 就是把xml字符串轉換爲InputStream
- String xmlString = "<?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>";
- //轉換爲inputStream類型
- InputStream is = new ByteArrayInputStream(xmlString.getBytes("UTF-8"));
二、DOM生成XML
寫完解析 我們來寫生成
也是使用上面的數據
下面是生成的代碼,註釋都寫了
- /**
- * 生成xml
- * */
- public void createXML() {
- // TODO Auto-generated method stub
- // 模擬數據
- List<Values> list = createValues();
- DocumentBuilderFactory builderFactory = DocumentBuilderFactory
- .newInstance();
- try {
- DocumentBuilder builder = builderFactory.newDocumentBuilder();
- Document document = builder.newDocument();
- // 建立根節點 person
- Element element = document.createElement("persons");
- // 添加到document
- document.appendChild(element);
- for (int i = 0; i < list.size(); i++) {
- Values values = list.get(i);
- // 建立節點person
- Element person = document.createElement("person");
- // 添加id屬性
- person.setAttribute("id", values.get_id());
- // 把節點添加到document
- element.appendChild(person);
- // 添加name元素
- Element name = document.createElement("name");
- //給name元素設置值
- name.setTextContent(values.get_name());
- //添加到person節點
- person.appendChild(name);
- // 添加age元素
- Element age = document.createElement("age");
- age.setTextContent(values.get_age());
- person.appendChild(age);
- }
- //設置輸出結果
- DOMSource domSource = new DOMSource(document);
- StringWriter writer = new StringWriter();
- StreamResult result = new StreamResult(writer);
- TransformerFactory factory = TransformerFactory.newInstance();
- Transformer transformer = factory.newTransformer();
- //開始把Document映射到result
- transformer.transform(domSource, result);
- Toast.makeText(activity, writer.toString(), Toast.LENGTH_LONG).show();
- } catch (Exception e) {
- // TODO: handle exception
- e.printStackTrace();
- }
- }
運行方法之後 如果顯示下面的圖,那就說明生成成功了
下面給出測試代碼生成的方法
- private List<Values> createValues() {
- // 模擬數據
- List<Values> list = new ArrayList<Values>();
- Values values = new Values();
- values.set_id("23");
- values.set_name("李磊");
- values.set_age("30");
- list.add(values);
- values = new Values();
- values.set_id("20");
- values.set_name("韓梅梅");
- values.set_age("25");
- list.add(values);
- return list;
- }
概括流程:
- //創建Document
- // ↓↓
- //創建主節點 添加到document
- // ↓↓
- //創建節點 添加到主節點
- // ↓↓
- //創建元素 設置值 添加到節點
- // ↓↓
- //生成成功
DOM方式的解析和生成已經講完了
下面一章將講解SAX的解析和生成