1. 程式人生 > >解析xml並去讀寫相應資料

解析xml並去讀寫相應資料

一、解析xml字串步驟

有些比較老的服務會通過傳輸xml字串來進行傳遞引數

對於這種場景,(在此採用dom4j的方式解析)獲取資料步驟如下:

    //將xml字串轉為Document格式
    Document doc = DocumentHelper.parseText(xml_String);
    //定位獲取某節點
    Node node = doc.selectSingleNode("/MESSAGE/DATASET/DATA/ITEM[3]");
    //強制轉為element元素
    Element element = (Element) node;
    //根據元素獲取屬性對應值
    String messageSequence = element.attribute(1).getValue();

說明一點:查詢節點,分為兩種查詢

(1)一層一層遍歷,直到找到對應節點----------前提是不清楚xml結構或者xml結構會變化

(2)根據層級關係直接查詢單個節點Node-----------前提當然是已知xml結構並且xml結構不會變化

   Node node = doc.selectSingleNode("/MESSAGE/DATASET/DATA/ITEM[3]");

二、在此單獨說一下xml的層級關係以及節點內的層級關係:

xml其實有和html類似的標籤關係,一出便成對存在或者以/>結尾

(1)對於標籤名,同一父標籤下的相同子標籤,可以使用陣列的形式獲取,如第一個item:ITEM[1]。下標從1開始

(2)對於屬性值,同一標籤下的標籤,可以使用element.attribute(i)的方式獲取,如第二個屬性val,element.attribute(1).getValue()下標是從0開始的

三、xml示例如下

<?xml version="1.0" encoding="UTF-8"?>
<MESSAGE>
    <DATASET name="data1" asd="asd">
        <DATA>
            <ITEM key="AAA" val="001" aaa="aaa"/>
            <ITEM key="BBB" val="002" bbb="bbb"/>
        </DATA>
    </DATASET>

    <DATASET name="data2">
        <DATA>
            <ITEM key="CCC" val="003"/>
            <CONDITION rel="PPP">
                <CONDITION rel="QQQ">
                    <ITEM key="DDD" val="004"/>
                </CONDITION>
                <ITEM key="EEE" val="005"/>
                <ITEM key="FFF" val="006"/>
 	            <CONDITION rel="OOO">
		            <ITEM key="GGG" val="007"/>
		            <ITEM key="HHH" val="008"/>
	             </CONDITION>
            </CONDITION>
        </DATA>
    </DATASET>
</MESSAGE>

四、修改xml屬性值步驟

廢話不多說先上程式碼

     SAXReader reader = new SAXReader();
     //將檔案讀取為Document
     Document document = reader.read(new    File("src/main/resources/static/response.xml"));
     //定位到某個節點
     Node node = document.selectSingleNode("/MESSAGE/DATASET/DATA/ITEM[1]");
     //將節點強制轉為元素
     Element element = (Element) node;
     //查詢屬性並設定值
     element.attribute(2).setValue("123456");
     //查詢屬性並列印獲取屬性值
     System.out.print(element.attribute(2).getValue());
     //將修改後的xml轉為字串
     String res = document.asXML();
     System.out.print(res);

說一點注意點:獲取檔案路徑通常分為相對路徑和絕對路徑,今天測試使用相對路徑獲取的時候一直報找不到檔案,嘗試採用專案根路徑來獲取就可以。等有時間必須分析一下這個問題

五、新增節點

1、在父節點依次在最下方新增子節點


            /**
             * 讀取xml轉為Document
             */
            SAXReader reader = new SAXReader();
            Document document = reader.read(new File("src/main/resources/template/.xml"));
            /**
            * 獲取節點
            */
            Node node = document.selectSingleNode("/MESSAGE/DATASET/DATA/ITEM[3]");
            Element element = (Element) node;
            
             /**
             * 新增ITEM節點,並在節點中新增key和value屬性
             */
            Element item = element.addElement("ITEM");
            item.addAttribute("key", "test_key")
                .addAttribute("value", "test");
             

2、在指定位置新增元素

實現原理就是將所有節點插入到list中,新建一個元素插入到已有的指定位置。

上程式碼:

node = document.selectSingleNode("/ROOT/NODE1");
element = (Element) node;
List<Element> list = element.elements();
Element item = DocumentHelper.createElement("CHILD");
item.addAttribute("key_test", "test")
    .addAttribute("value", "hello world");
//在第二個子元素下新增一個元素
list.add(2, item);

六、將字串轉為xml檔案

             /**
             * 輸出為xml檔案 建立一種輸出格式,每個節點元素可自動換行
             */
            OutputFormat outputStream = OutputFormat.createPrettyPrint();
            outputStream.setEncoding("UTF-8");
            XMLWriter xmlWriter =
                new XMLWriter(new FileWriter(new File("src/main/resources/template/test02.xml")), outputStream);
            xmlWriter.write(document);
            xmlWriter.close();

七、對於xml檔案讀取解析主流方法有以下四種:

1、dom

2、jdom

3、dom4j----最推薦使用的

4、sax

總結如下:

      DOM4J效能最好,連Sun的JAXM也在用DOM4J。目前許多開源專案中大量採用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J來讀取XML配置檔案。如果不考慮可移植性,那就採用DOM4J。
      JDOM和DOM在效能測試時表現不佳,在測試10M文件時記憶體溢位。在小文件情況下還值得考慮使用DOM和JDOM。雖然JDOM的開發者已經說明他們期望在正式發行版前專注效能問題,但是從效能觀點來看,它確實沒有值得推薦之處。另外,DOM仍是一個非常好的選擇。DOM實現廣泛應用於多種程式語言。它還是許多其它與XML相關的標準的基礎,因為它正式獲得W3C推薦(與基於非標準的Java模型相對),所以在某些型別的專案中可能也需要它(如在JavaScript中使用DOM)。
      SAX表現較好,這要依賴於它特定的解析方式-事件驅動。一個SAX檢測即將到來的XML流,但並沒有載入到記憶體(當然當XML流被讀入時,會有部分文件暫時隱藏在記憶體中)