天天看點

XML解析——DOM

  1. DOM(Document Object Model)

    DOM是用與平台和語言無關的方式表示XML文檔的官方W3C标準。DOM是以層次結構組織的節點或資訊片斷的集合。這個層次結構允許開發人員在樹中尋找特定資訊。分析該結構通常需要加載整個文檔和構造層次結構,然後才能做任何工作。由于它是基于資訊層次的,因而DOM被認為是基于樹或基于對象的。

    【優點】

    ①允許應用程式對資料和結構做出更改。

    ②通路是雙向的,可以在任何時候在樹中上下導航,擷取和操作任意部分的資料。

    ③基于樹結構,比較耗資源,适用于多次通路XML。

    【缺點】

    ①通常需要加載整個XML文檔來構造層次結構,消耗資源大。

2.DOM讀取XML的步驟:

1、建立解析器工廠對象

DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();

2、由解析器工廠對象建立解析器對象

DocumentBuilder db=dbf.newDocumentBuilder();

3、由解析器對象對指定的XML檔案進行解析,建構相應的DOM樹,建立Document對象。

Document document=db.parse(“XML檔案路徑”);

3.對XML檔案進行查詢,修改和删除。

1、查詢。(對TEXT_NODE類型的節點,輸出其text) 方法: print(document);

public static void print(Node n) {  //把document轉為Node型
        //擷取所有的孩子節點
        NodeList nl = n.getChildNodes(); 
        for (int i = ; i < nl.getLength(); i++) {
            Node node = nl.item(i);
            //判斷是否為TEXT_NODE類型,true 的話就繼續判斷
            if (node.getNodeType() == Node.TEXT_NODE) {  
                //XML中換行空格也是一種節點,需要把他們去掉,要不然輸出時會有很多空格
                if (!"".equals(node.getTextContent().trim())) {
                    //列印文本
                    System.out.println(node.getTextContent());
                }
            } else {
                //不是TEXT_NODE類型,則進行遞歸判斷,直到列印出所有的TEXT_NODE類型
                print(node);
            }
        }
    }  
           

2、更新節點 update(Node node);

1.先找到你所要改的節點:

Node n1= doc.getElementsByTagName(“student”).item(0);//如,我要找所有student的節點的 第一個student,把它當參數穿進去。

public static void update(Node node) {
        //判斷是ELEMENT_NODE類型的結點,
        if (node.getNodeType() == Node.ELEMENT_NODE) {
            //Node轉換為子類Element,有更多的方法
            Element element = (Element) node;
            //設定屬性
            element.setAttribute("address", "北京");
            //得到子節點name中的第一個(因為一個student中,其實可以設定很多個<name>标簽,我們這隻有一個,是以取其第一個)
            Element name = (Element) element.getElementsByTagName("name").item();
            //設定文本
            name.setTextContent("奧巴馬");
        }

    }
           

3、删除節點 remove(Document doc);

public static void remove(Document doc) {
        //擷取第2個student ,删除它
        Element e = (Element) doc.getElementsByTagName("student").item();
        //先擷取它的父節點,再通過父節點删除自己(自己不能删除自己)
        e.getParentNode().removeChild(e);
    }
           

4、新增節點 add(Document doc);

public static void add(Document doc) throws Exception {
        // 先找到跟元素,因為DOM是樹狀,的找到跟節點再去添加分支
        Element root = (Element) doc.getElementsByTagName("students").item();
        // 建立一個student
        Element student = doc.createElement("student");
        // 設定屬性
        student.setAttribute("address", "長沙");
        // 建立ID name course scores
        Element ID = doc.createElement("id");
        ID.setTextContent("3");
        Element name = doc.createElement("name");
        name.setTextContent("瑞文");
        Element course = doc.createElement("course");
        course.setTextContent("英雄聯盟");
        Element scores = doc.createElement("scores");
        scores.setTextContent("120");
        // 把它們都加到student裡面去
        student.appendChild(ID);
        student.appendChild(name);
        student.appendChild(course);
        student.appendChild(scores);
        // 再把student 加到root 下面
        root.appendChild(student);
        // 把他寫入XML文檔
        transformTo(doc);
    }
           

5、以上的操作都是把XML讀入記憶體裡面,在記憶體裡面進行修改,而我們就要把我們修改後的記憶體裡面的XML 寫入到實際的(硬碟)的XML中。 transformTo(Document doc);

public static void transformTo(Document doc) throws Exception {
        // 同樣的得到轉換工廠
        TransformerFactory factory = TransformerFactory.newInstance();
        //獲得其執行個體
        Transformer transformer = factory.newTransformer();
        //這個是用來限制格式的,但是你的XML檔案就要有一個DTD 檔案,在檔案寫入時,會按照你的DTD檔案的格式來,而不會全部都擠在一行
        transformer.setOutputProperty(javax.xml.transform.OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId());
        //2個參數,第一個是源,即你的document,第二個是輸出流,指向你的XML檔案路徑。也可以查API
        transformer.transform(new DOMSource(doc), new StreamResult("20160829/students.xml"));
    }