【建議收藏】一份阿里大牛花了三天整理出來的XML學習筆記,寫的非常詳細
1. 什麼是XML?
XML 指可擴充套件標記語言(EXtensible Markup Language)
XML 是一種標記語言,很類似 HTML
XML 的設計宗旨是傳輸資料,而非顯示資料
XML 標籤沒有被預定義。您需要自行定義標籤。
XML 被設計為具有自我描述性。
XML 是 W3C 的推薦標準
2. 為什麼使用XML?
我們沒有XML這種語言之前,我們使用的是String作為兩個程式之間的通訊!現在問題就來了,如果我們傳輸的是帶有關係型結構的資料,String怎麼表達呢?String對關係型資料不擅長,要是描述起來也難免會有歧義的時候!
HTML語言本身就有缺陷:
標記都是固定的,不能自定義。HTML語言中有什麼標記就只能用什麼標記
HTML沒有實現真正的國際化
3. XML的用途
①:配置檔案(例子:Tomcat的web.xml,server.xml……),XML能夠非常清晰描述出程式之間的關係
②:程式間資料的傳輸,XML的格式是通用的,能夠減少交換資料時的複雜性!
③:充當小型資料庫,如果我們的資料有時候需要人工配置的,那麼XML充當小型的資料庫是個不錯的選擇,程式直接讀取XML檔案顯然要比讀取資料庫要快呢!
4. xml的技術架構
XML被設計為“什麼都不做”,XML資料或XML文件只用於組織、儲存資料,除此之外的資料生成、讀取、傳送、存取等等操作都與XML本身無關!
於是乎,想要操作XML,就需要用到XML之外的技術了:
為XML定規則:現在一般使用DTD或Schema技術,當然了Schema技術更為先進!
解析XML的資料:一般使用DOM或者SAX技術,各有各的優點
提供樣式:XML一般用來儲存資料的,但設計者野心很大,也想用來顯示資料(但沒人用XML來顯示資料),就有了XSLT(eXtensiable Stylesheet Language Transformation)可擴充套件樣式轉換語言
5. XML語法
5.1 文件宣告
XML宣告放在XML的第一行
version —— 版本
encoding —— 編碼standalone–獨立使用 —— 預設是no。standalone表示該xml是不是獨立的。
如果是yes,則表示這個XML文件時獨立的,不能引用外部的DTD規範檔案;
如果是no,則該XML文件不是獨立的,表示可以引用外部的DTD規範文件。
正確的文件宣告格式,屬性的位置不能改變!
<!-- 正確的文件宣告格式,屬性的位置不能改變! --> <?xml version="1.0" encoding="utf-8" standalone="no"?>
5.2 元素
元素中需要值得注意的地方:
XML元素中的出現的空格和換行都會被當做元素內容進行處理
每個XML文件必須有且只有一個根元素
元素必須閉合
大小寫敏感
不能交叉巢狀
不能以數字開頭
XML的語法是規範的!不要隨意亂寫!
5.3 屬性
屬性是作為XML元素中的一部分的,命名規範也是和XML元素一樣的!
<!-- 屬性名是name,屬性值是chinese --> <china name="chinese"> </china>
5.4 CDATA
在編寫XML檔案時,有些內容可能不想讓解析引擎解析執行,而是當作原始內容處理。
遇到此種情況,可以把這些內容放在CDATA區裡,對於CDATA區域內的內容,XML解析程式不會處理,而是直接原封不動的輸出。
<![CDATA[ 內容 ]]>
5.5 轉義字元
對於一些單個字元,若想顯示其原始樣式,也可以使用轉義的形式予以處理。
6. XML解析
6.1 XML解析方式有兩種:
①:dom (Document Object Model) :文件物件模型,是W3C組織推薦解析XML的一種方式。
②:sax (Simple API For XML):它是XML社群的標準,幾乎所有XML解析器都支援它!
6.2 XML解析操作
應用程式不是直接對XML文件進行操作的,而是由XML解析器對XML文件進行分析,然後應用程式通過XML解析器所提供的DOM介面或者SAX介面對分析結果進行操作,從而間接地實現了對XML文件的訪問!
7. Java解析XML
xml文件中的資料
<?xml version="1.0" encoding="utf-8" standalone="no"?> <china> <guangzhou >廣州</guangzhou> <shenzhen>深圳</shenzhen> <beijing>北京</beijing> <shanghai>上海</shanghai> </china>
7.1 DOM解析
7.1.1 遍歷
public class Main{ public static void main(String[] args) throws ParserConfigurationException , IOException, SAXException { //API規範:需要用一個工廠來造解析器物件,先造了一個工廠 DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); //獲取解析器物件 DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); //解析XML文件,得到了代表XML文件的Document物件! Document document = documentBuilder.parse(new File("test.xml")); list(document); } private static void list(Node node){ if(node.getNodeType() == Node.ELEMENT_NODE){ System.out.println(node.getNodeName()); } NodeList nodelist = node.getChildNodes(); for(int i = 0;i<nodelist.getLength();i++){ Node child = nodelist.item(i); list(child); } } } /* Output: china guangzhou shenzhen beijing shanghai */
7.1.2 查詢
private static void read(Document document){ NodeList nodelist = document.getElementsByTagName("a"); Node node = nodelist.item(0); String value = node.getTextContent(); System.out.println(value); } /* Output: 廣州 */
7.1.3 增加
增加到XML文件中的最後
private static void add(Document document) throws TransformerException { //建立需要增加的節點 Element element = document.createElement("hangzhou"); //向節點新增文字內容 element.setTextContent("杭州"); //得到需要新增節點的父節點 Node parent = document.getElementsByTagName("china").item(0); //把需要增加的節點掛在父節點下面去 parent.appendChild(element); //獲取一個轉換器它需要工廠來造,那麼我就造一個工廠 TransformerFactory transformerFactory = TransformerFactory.newInstance(); //獲取轉換器物件 Transformer transformer = transformerFactory.newTransformer(); //把記憶體中的Dom樹更新到硬碟中 transformer.transform(new DOMSource(document),new StreamResult("test.xml")); }
增加到指定節點的前一個
private static void add2(Document document) throws TransformerException { //獲取到beijing節點 Node beijing = document.getElementsByTagName("beijing").item(0); //建立新的節點 Element element = document.createElement("guangxi"); //設定節點的文字內容 element.setTextContent("廣西"); //獲取到要建立節點的父節點, Node parent = document.getElementsByTagName("china").item(0); //將guangxi節點插入到beijing節點之前! parent.insertBefore(element, beijing); //將記憶體中的Dom樹更新到硬碟檔案中 TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.transform(new DOMSource(document), new StreamResult("city.xml")); }
7.1.4 刪除
private static void delete(Document document) throws TransformerException { //獲取到beijing這個節點 Node node = document.getElementsByTagName("beijing").item(0); //獲取到父節點,然後通過父節點把自己刪除了 node.getParentNode().removeChild(node); //把記憶體中的Dom樹更新到硬碟檔案中 TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.transform(new DOMSource(document),new StreamResult("test.xml")); }
7.1.5 修改
private static void updata(Document document) throws TransformerException { //獲取到廣州的結點 Node node = document.getElementsByTagName("guangzhou").item(0); node.setTextContent("廣州你好"); //將記憶體中的Dom樹更新到硬碟檔案中 TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.transform(new DOMSource(document),new StreamResult("test.xml")); }
7.1.6 操作屬性
private static void updataAttribute(Document document) throws TransformerException { //獲取到guangzhou節點 Node node = document.getElementsByTagName("guangzhou").item(0); //現在node節點沒有增加屬性的方法,所以我就要找它的子類---Element Element guangzhou = (Element) node; guangzhou.setAttribute("play","gzchanglong"); //如果要刪除屬性就用removeAttribute()方法 //將記憶體中的Dom樹更新到硬碟檔案中 TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.transform(new DOMSource(document),new StreamResult("test.xml")); }
7.2 dom4j解析
需要匯入開發包
7.2.1 為什麼要有dom4j?
dom缺點:比較耗費記憶體
sax缺點:只能對xml檔案進行讀取,不能修改,新增,刪除
dom4j:既可以提高效率,同時也可以進行crud操作
7.2.2 獲取Document物件
①:讀取XML檔案,獲得document物件(這種最常用)
SAXReader reader = new SAXReader(); Document document = reader.read(new File("input.xml"));
②:解析XML形式的文字,得到document物件
String text = "<members></members>"; Document document=DocumentHelper.parseText(text);
③:主動建立document物件.
Document document =DocumentHelper.createDocument(); //建立根節點 Element root = document.addElement("members");
7.2.3 查詢
XML檔案
<?xml version="1.0" encoding="UTF-8" ?> <person> <name littleName="zk">xzk</name> <age>20</age> </person>
一般查詢
public void read() throws DocumentException { //獲取到解析器 SAXReader saxReader = new SAXReader(); //獲取到XML檔案的流物件 InputStream inputStream = dom4j11.class.getClassLoader().getResourceAsStream("1.xml"); //通過解析器讀取XML檔案 Document document = saxReader.read(inputStream); //獲取得到根節點 Element root = document.getRootElement(); //獲取得到name節點 Element name = root.element("name"); //得到了name節點,就可以獲取name節點的屬性或者文字內容了! String text = name.getText(); String attribute = name.attributeValue("littleName"); System.out.println("文字內容是:" + text); System.out.println("屬性內容是:" + attribute); } /* Output: 文字內容是:xzk 屬性內容是:zk */
多層結構的查詢
//獲取得到根節點 Element root = document.getRootElement(); //一層一層地獲取到節點 Element element = root.element("guangdong").element("guangzhou").element("luogang"); String value = element.getText(); System.out.println(value);
7.2.4 增加
public void add() throws Exception { //獲取到解析器 SAXReader saxReader = new SAXReader(); //獲取到XML檔案的流物件 InputStream inputStream = dom4j11.class.getClassLoader().getResourceAsStream("1.xml"); //通過解析器讀取XML檔案 Document document = saxReader.read(inputStream); //創建出新的節點,為節點設定文字內容 Element newElement = DocumentHelper.createElement("name"); newElement.setText("ouzicheng"); //獲取到根元素 Element root = document.getRootElement(); //把新建立的name節點掛在根節點下面 root.add(newElement); //建立帶有格式的物件 OutputFormat outputFormat = OutputFormat.createPrettyPrint(); //設定編碼,預設的編碼是gb2312,讀寫的編碼不一致,會導致亂碼的! outputFormat.setEncoding("UTF-8"); //建立XMLWriter物件 XMLWriter xmlWriter = new XMLWriter(new FileWriter("2.xml"), outputFormat); //XMLWriter物件寫入的是document xmlWriter.write(document); //關閉流 xmlWriter.close(); }
在指定的位置增加節點
//建立一個新節點 Element element = DocumentHelper.createElement("name"); element.setText("ouzciheng"); //獲取得到person下所有的節點元素! List list = document.getRootElement().elements(); //將節點新增到指定的位置上 list.add(1, element);
7.2.5 修改
//獲取得到age元素 Element age = document.getRootElement().element("age"); age.setText("9999");
XMLWriter和獲取Document物件的程式碼和前面的都是一樣的
7.2.6 刪除
//獲取得到age節點 Element age = document.getRootElement().element("age"); //得到age節點的父節點,使用父節點的remove刪除age節點! age.getParent().remove(age);
XMLWriter和獲取Document物件的程式碼和前面的都是一樣的
最後
感謝你看到這裡,看完有什麼的不懂的可以在評論區問我,覺得文章對你有幫助的話記得給我點個贊,每天都會分享java相關技術文章或行業資訊,歡迎大家關注和轉發文章!