1. 程式人生 > 實用技巧 >【建議收藏】一份阿里大牛花了三天整理出來的XML學習筆記,寫的非常詳細

【建議收藏】一份阿里大牛花了三天整理出來的XML學習筆記,寫的非常詳細

1. 什麼是XML?

XML 指可擴充套件標記語言(EXtensible Markup Language)
XML 是一種標記語言,很類似 HTML
XML 的設計宗旨是傳輸資料,而非顯示資料
XML 標籤沒有被預定義。您需要自行定義標籤。
XML 被設計為具有自我描述性。
XML 是 W3C 的推薦標準

2. 為什麼使用XML?

我們沒有XML這種語言之前,我們使用的是String作為兩個程式之間的通訊!現在問題就來了,如果我們傳輸的是帶有關係型結構的資料,String怎麼表達呢?String對關係型資料不擅長,要是描述起來也難免會有歧義的時候!

HTML語言本身就有缺陷:

標記都是固定的,不能自定義。HTML語言中有什麼標記就只能用什麼標記

HTML標籤本身就缺少含義 (tr標籤裡面什麼內容都能放進去,不規範!)
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相關技術文章或行業資訊,歡迎大家關注和轉發文章!