XML文件解析:DOM解析與DOM的增刪改查
阿新 • • 發佈:2018-12-18
DOM解析XML的概述:
DOM解析優點:
整個文件樹在記憶體中,便於操作;
可以修改,刪除、重新排列XML;
可以隨機訪問任何一個節點,訪問效率高。
DOM解析的缺點:
佔用記憶體大,佔用資源多
解析速度慢
DOM解析適用場合:
需多次訪問這些資料;
對解析效率要求不高;
硬體資源充足(記憶體、CPU)。
DOM解析XML檔案的步驟:
// 1、 獲取解析器類工廠 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 2、根據解析器工廠獲得解析器 DocumentBuilder db = factory.newDocumentBuilder(); // 3、根據解析器獲得document物件 Document document = db.parse("dtd/books.xml");//根據自己的XML檔案路徑填寫
得到了DOCUMENT物件document,就相當於得到了整個xml檔案
接下來通過程式碼進行例項的分析:
books.xml:
<?xml version="1.0" encoding="gbk" standalone="no"?><books> <book language="zh"> <name>紅樓夢</name> <author>曹雪芹</author> <price>76</price> </book> <book language="en"> <name>西遊記</name> <author>吳承恩</author> <price>89</price> </book> </books>
DOM方式解析XML(通過簡單的獲取元素和屬性):
public class Demo1 { @Test public void Test() { // 1、 獲取解析器類工廠 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 2、根據解析器工廠獲得解析器 try { DocumentBuilder db = factory.newDocumentBuilder(); // 3、根據解析器獲得document物件 Document document = db.parse("dtd/books.xml"); // 根據document物件獲得節點值 NodeList nodes1 = document.getElementsByTagName("book");// 根據節點的元素名獲取元素,返回的book節點可能不只一個,返回的是一個NodeList物件 System.out.println(nodes1.getLength()); for (int i = 0; i < nodes1.getLength(); i++) { Node node = nodes1.item(i);// 根據元素獲取元素節點book //根據節獲元素屬性 NamedNodeMap attributes = node.getAttributes(); for (int j = 0; j < attributes.getLength(); j++) { Node item = attributes.item(j); System.out.println(item.getNodeName());//得到屬性名 System.out.println(item.getNodeValue());//得到屬性值 } System.out.println(node.getNodeName());// 得到book元素(可能不只一個book元素) NodeList childNodes = node.getChildNodes();// 根據上一步獲得的book節點,獲取book節點下面的子節點 for (int j = 0; j < childNodes.getLength(); j++) { Node text = childNodes.item(j); // 根據節點名稱和xml檔案中的元素名稱做比較equals的列印輸出 if (text.getNodeName().equals("name")) { System.out.println(text.getTextContent()); } if (text.getNodeName().equals("author")) { System.out.println(text.getTextContent()); } if (text.getNodeName().equals("price")) { System.out.println(text.getTextContent()); } } } } catch (ParserConfigurationException | SAXException | IOException e) { e.printStackTrace(); } } }
接下來對XML檔案進行簡單的增、刪、改操作:
增加元素和屬性操作:
在book後面新增 1997-12-15 節點: 1、新增的位置 2、將元素創建出來
// dom元素增加操作
@Test
public void Test1() throws UnsupportedEncodingException, FileNotFoundException {
// 1、獲取document物件
Document document = DomUtil.getDocument("xml/books.xml");
// 2、問題分析:book後面新增<data>1997-12-15</data>節點
// 2.1首先元素新增到那個位置
Node book = document.getElementsByTagName("book").item(0);
// 2.2元素要創建出來
Element data = document.createElement("data");
data.setTextContent("1997-12-15");
book.appendChild(data);
// 回寫操作
DomUtil.backWrite(document, "xml/books.xml");
}
@Test
// 新增元素的屬性
public void Test2() throws UnsupportedEncodingException, FileNotFoundException {
// 獲得document物件
Document document = DomUtil.getDocument("xml/books.xml");
Element book = (Element) document.getElementsByTagName("book").item(0);
book.setAttribute("language", "英文");
// 回寫操作
DomUtil.backWrite(document, "xml/books.xml");
}
刪除元素和屬性操作:
// dom刪除元素
@Test
public void Test6() throws UnsupportedEncodingException, FileNotFoundException {
// 獲取document物件
Document document = DomUtil.getDocument("xml/books.xml");
// 獲取book元素
Node data = document.getElementsByTagName("data").item(0);
data.getParentNode().removeChild(data);// 先獲取父節點,在根據父節點去刪除子節點
// 回寫操作
DomUtil.backWrite(document, "xml/books.xml");
}
@Test
// dom刪除元素的屬性
public void Test4() throws UnsupportedEncodingException, FileNotFoundException {
// 獲取document物件
Document document = DomUtil.getDocument("xml/books.xml");
// 獲取book元素
Element book = (Element) document.getElementsByTagName("book").item(0);
book.removeAttribute("language");
// 回寫操作
DomUtil.backWrite(document, "xml/books.xml");
}
修改元素和屬性操作:
@Test
// 修改元素內容 name中的內容
public void fun1() throws UnsupportedEncodingException, FileNotFoundException {
// 獲取document物件
Document document = DomUtil.getDocument("dtd/books.xml");
// 得到name元素物件
NodeList authors = document.getElementsByTagName("author");
Node author = authors.item(0);// 得到第一個元素為author節點,假設知道
// 修改節點內容
author.setTextContent("小曹");
// 此時需要對author中的內容進行回寫操作
// 回寫操作
DomUtil.backWrite(document, "dtd/books.xml");
}
// 修改元素屬性
@Test
public void fun2() throws UnsupportedEncodingException, FileNotFoundException {
// 獲取document物件
Document document = DomUtil.getDocument("dtd/books.xml");
// 獲取需要修改的元素
// 獲取得到的元素是NodeList的返回值,.item(0)之後是Node的返回值,但是不能獲取單個屬性,查文件發現Element是可以獲取得到單個屬性
Element en = (Element) document.getElementsByTagName("book").item(0);
en.setAttribute("language", "en");
// 回寫操作
DomUtil.backWrite(document, "dtd/books.xml");
}
將回寫操作和獲得document物件進行封裝:
//將獲得document物件進行封裝
public static Document getDocument(String uri) {
// 1、建立解析器類工廠
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 2、根據解析器工廠生產解析器
try {
DocumentBuilder db = factory.newDocumentBuilder();
// 3、根據生產的解析器獲取document物件
Document document = db.parse(uri);
return document;
} catch (IOException | SAXException | ParserConfigurationException e) {
e.printStackTrace();
}
return null;
}
//將回寫操作進行封裝
public static void backWrite(Document document, String uri)
throws UnsupportedEncodingException, FileNotFoundException {
// 1、獲得修改器工廠
TransformerFactory factory = TransformerFactory.newInstance();
// 2、根據修改器工廠獲得修改器
try {
Transformer tf = factory.newTransformer();
// 3、根據修改器進行回寫操作
// tf.transform(new DOMSource(document), new StreamResult(new
// File("dtd/books.xml")));
//解決亂碼問題,出現問題的原因是:儲存的XML檔案的編碼和解析是的編碼不一致
tf.transform(new DOMSource(document),
new StreamResult(new OutputStreamWriter(new FileOutputStream(uri), "GBK")));// 解決亂碼問題
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
}