解析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流被讀入時,會有部分文件暫時隱藏在記憶體中)