Java利用DOM解析XML的學(xué)習(xí)指南
一、DOM原理:XML的"克隆人戰(zhàn)爭(zhēng)"
想象你要復(fù)制整個(gè)迪士尼樂(lè)園:
全量加載術(shù):把XML文件整個(gè)吞進(jìn)內(nèi)存,變成一顆節(jié)點(diǎn)樹(就像把城堡圖紙轉(zhuǎn)成3D模型)
隨機(jī)訪問(wèn)特權(quán):可以隨時(shí)瞬移到任意角落:“我要修改第三塊磚的顏色!”(而SAX只能從頭看到尾)
修改超能力:支持增刪改查,像玩《模擬人生》一樣隨意改造XML世界
二、實(shí)戰(zhàn)演練:用DOM搭建"程序員主題樂(lè)園"
項(xiàng)目藍(lán)圖(programmer_park.xml):
<主題樂(lè)園 名稱="996快樂(lè)谷"> <區(qū)域 類型="代碼深淵" geohash="wx4g0b1"> <設(shè)施 id="1"> <名稱>無(wú)限續(xù)杯咖啡廳</名稱> <危險(xiǎn)等級(jí)>★★★★☆</危險(xiǎn)等級(jí)> </設(shè)施> <設(shè)施 id="2"> <名稱>需求變更過(guò)山車</名稱> <危險(xiǎn)等級(jí)>★★★★★</危險(xiǎn)等級(jí)> </設(shè)施> </區(qū)域> </主題樂(lè)園>
建筑師工具包(DomArchitect.java)
import org.w3c.dom.*; import javax.xml.parsers.*; import javax.xml.transform.*; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; public class DomArchitect { public static void main(String[] args) throws Exception { // 裝載整個(gè)樂(lè)園到內(nèi)存 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document park = builder.parse("programmer_park.xml"); // 打印所有危險(xiǎn)設(shè)施 NodeList rides = park.getElementsByTagName("設(shè)施"); System.out.println("?? 高危設(shè)施列表:"); for (int i=0; i<rides.getLength(); i++) { Element ride = (Element) rides.item(i); String name = ride.getElementsByTagName("名稱").item(0).getTextContent(); String level = ride.getElementsByTagName("危險(xiǎn)等級(jí)").item(0).getTextContent(); System.out.println(name + " | 危險(xiǎn)指數(shù):" + level); } // 新增一個(gè)奪命設(shè)施 Element newRide = park.createElement("設(shè)施"); newRide.setAttribute("id", "3"); Element name = park.createElement("名稱"); name.appendChild(park.createTextNode("Deadline蹦極臺(tái)")); Element level = park.createElement("危險(xiǎn)等級(jí)"); level.appendChild(park.createTextNode("★★★★★★")); // 突破五星! newRide.appendChild(name); newRide.appendChild(level); park.getDocumentElement().getFirstChild().appendChild(newRide); // 保存修改后的樂(lè)園(小心內(nèi)存泄漏!) Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.transform(new DOMSource(park), new StreamResult("programmer_park_modified.xml")); } }
運(yùn)行結(jié)果:
?? 高危設(shè)施列表:
無(wú)限續(xù)杯咖啡廳 | 危險(xiǎn)指數(shù):★★★★☆
需求變更過(guò)山車 | 危險(xiǎn)指數(shù):★★★★★
(生成的新XML會(huì)多出一個(gè)"Deadline蹦極臺(tái)",危險(xiǎn)指數(shù)突破天際?。?/p>
三、DOM vs SAX:建筑師與偵探的巔峰對(duì)決
DOM建筑師 | SAX偵探 | |
---|---|---|
內(nèi)存消耗 | 需要搬來(lái)整個(gè)建材市場(chǎng)(全量加載) | 只帶偵探工具包(流式處理) |
操作方式 | 可以隨意拆墻裝修(隨機(jī)修改) | 只能做現(xiàn)場(chǎng)記錄(只讀) |
響應(yīng)速度 | 裝修前要先運(yùn)材料(初始化慢) | 到達(dá)現(xiàn)場(chǎng)立即開工(啟動(dòng)快) |
適用場(chǎng)景 | 需要改結(jié)構(gòu)的精致小別墅 | 快速搜查犯罪現(xiàn)場(chǎng)的超大倉(cāng)庫(kù) |
四、DOM操作三大"騷操作"
1.XPath閃電定位
用XPath直接空降到指定節(jié)點(diǎn),像使用傳送門:
XPath xpath = XPathFactory.newInstance().newXPath(); Node node = (Node) xpath.evaluate("http://設(shè)施[名稱='需求變更過(guò)山車']", park, XPathConstants.NODE);
2.屬性隱身術(shù)
動(dòng)態(tài)修改geohash坐標(biāo),讓設(shè)施"瞬間移動(dòng)":
Element area = (Element) park.getElementsByTagName("區(qū)域").item(0); area.setAttribute("geohash", "wx4g0b9"); // 從深淵傳送到廁所
3.節(jié)點(diǎn)克隆大法
復(fù)制過(guò)山車并改名,省時(shí)省力:
Node clonedRide = rides.item(1).cloneNode(true); ((Element)clonedRide).setAttribute("id", "4"); clonedRide.getChildNodes().item(0).setTextContent("需求復(fù)活過(guò)山車");
五、DOM的致命陷阱
1.內(nèi)存黑洞
加載1GB的XML文件 ≈ 在內(nèi)存里造航空母艦(小心OOM空襲?。?/p>
2.空白節(jié)點(diǎn)鬼打墻
XML中的換行符會(huì)被視為Text節(jié)點(diǎn),遍歷時(shí)可能踩坑:
// 錯(cuò)誤示范:直接取第一個(gè)子節(jié)點(diǎn)可能是空白文本節(jié)點(diǎn)! // Element name = (Element) ride.getFirstChild(); // 正確姿勢(shì):過(guò)濾文本節(jié)點(diǎn) NodeList children = ride.getChildNodes(); for (int i=0; i<children.getLength(); i++) { if (children.item(i).getNodeType() == Node.ELEMENT_NODE) { Element child = (Element) children.item(i); // 處理真實(shí)節(jié)點(diǎn) } }
3.線程安全驚魂
Document對(duì)象不是線程安全的!多個(gè)線程同時(shí)裝修會(huì)拆了你的樂(lè)高城堡。
六、DOM哲學(xué):內(nèi)存即世界
每個(gè)Element節(jié)點(diǎn)都是樂(lè)高積木
每個(gè)Text節(jié)點(diǎn)都是積木上的貼紙
每個(gè)Attribute都是積木的卡扣設(shè)計(jì)
到此這篇關(guān)于Java利用DOM解析XML的學(xué)習(xí)指南的文章就介紹到這了,更多相關(guān)Java DOM解析XML內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Flink開發(fā)IDEA環(huán)境搭建與測(cè)試的方法
這篇文章主要介紹了Flink開發(fā)IDEA環(huán)境搭建與測(cè)試的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03mybatis-plus QueryWrapper自定義查詢條件的實(shí)現(xiàn)
這篇文章主要介紹了mybatis-plus QueryWrapper自定義查詢條件的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08springboot 實(shí)現(xiàn)長(zhǎng)鏈接轉(zhuǎn)短鏈接的示例代碼
短鏈接服務(wù)通過(guò)將長(zhǎng)URL轉(zhuǎn)換成6位短碼,并存儲(chǔ)長(zhǎng)短鏈接對(duì)應(yīng)關(guān)系到數(shù)據(jù)庫(kù)中,用戶訪問(wèn)短鏈接時(shí),系統(tǒng)通過(guò)查詢數(shù)據(jù)庫(kù)并重定向到原始URL,實(shí)現(xiàn)快速訪問(wèn),本文就來(lái)介紹一下如何使用,感興趣的可以了解一下2024-09-09升級(jí)springboot3之自動(dòng)配置導(dǎo)入失效問(wèn)題及解決
這篇文章主要介紹了升級(jí)springboot3之自動(dòng)配置導(dǎo)入失效問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07Mybatis調(diào)用視圖和存儲(chǔ)過(guò)程的方法
MyBatis支持普通sql的查詢、視圖的查詢、存儲(chǔ)過(guò)程調(diào)用,是一種非常優(yōu)秀的持久層框架。接下來(lái)通過(guò)本文給大家介紹mybatis調(diào)用視圖和存儲(chǔ)過(guò)程的方法,感興趣的朋友一起看看吧2016-10-10Red?Hat?安裝JDK與IntelliJ?IDEA的詳細(xì)過(guò)程
YUM是基于Red Hat的Linux發(fā)行版的一個(gè)強(qiáng)大而用戶友好的包管理工具,這篇文章主要介紹了Red?Hat安裝JDK與IntelliJ IDEA,需要的朋友可以參考下2023-08-08SpringBoot如何在運(yùn)行時(shí)動(dòng)態(tài)添加數(shù)據(jù)源
這篇文章主要介紹了SpringBoot如何在運(yùn)行時(shí)動(dòng)態(tài)添加數(shù)據(jù)源,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10