XML文檔解析:DOM解析與DOM的增刪改查

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();
		}
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章