XML文件

是你得不到的人發表於2020-09-26

XML

基本概念

  • XML即可擴充套件標記語言(Extensible Markup Language)
  • W3C在1998年2月釋出1.0版本,2004年2月又釋出1.1版本,但因為1.1版本不能向下相容1.0版 本,所以1.1沒有人用
  • 同時,在2004年2月W3C又釋出了1.0版本的第三版。我們要學習的還是 1.0版本 !
  • 特點
    可擴充套件的, 標籤都是自定義的 語法十分嚴格

XML的作用

  • 作用

    功能說明
    儲存資料通常,我們在資料庫中儲存資料。不過,如果希望資料的可移植性更強,我們可以 把資料儲存 XML 檔案中
    配置檔案作為各種技術框架的配置檔案使用 (多)
    在網路中 傳輸客戶端可以使用XML格式向伺服器端傳送資料,伺服器接收到xml格式資料,進行解析

XML的語法

XML文件宣告格式

  • 文件宣告必須為結束

  • 文件宣告必寫在第一行

  • 語法格式

    <?xml version="1.0" encoding="UTF-8"?>
    
  • 屬性說明

    • versioin:指定XML文件版本。必須屬性,因為我們不會選擇1.1,只會選擇1.0
    • encoding:指定當前文件的編碼。可選屬性,預設值是utf-8

元素

  • Element 元素

    • 是XML文件中重要的組成部分
  • 元素的命名規則

    • 不能使用空格,不能使用冒號
    • xml 標籤名稱區分大小寫
    • XML 必須有且只有一個根元素
  • 語法格式

    <?xml version="1.0" encoding="UTF-8"?>
    <users>
        <hello> 大家好 </hello>
        <hello>    
            <a>你好</a> 
        </hello>
        <close/>
    </users>
    
  • 注意事項

    XML 必須有且只有一個根元素,它是所有其他元素的父元素,比如以上例項中 users 就是根元素

    普通元素的結構開始標籤、元素體、結束標籤組成

    元素體:元素體可以是元素,也可以是文字

    空元素:空元素只有開始標籤,而沒有結束標籤,但元素必須自己閉合

屬性

  • 屬性是元素的一部分,它必須出現在元素的開始標籤中

  • 屬性的定義格式

  • 屬性名=屬性值,其中屬性值必須使用單引或雙引

  • 一個元素可以有0~N個屬性,但一個元素中不能出現同名屬性 4. 屬性名不能使用空格、冒號等特殊字元,且必須以字母開頭

<bean id="" class=""> </bean>

註釋

  • XML的註釋,以 “<!–” 開始,以“–> ”結束。註釋內容會被XML解析器忽略

    <!-- 這是註釋 -->
    <users></users>
    

舉例

  • 舉例

    <employees>
        <employee eid="2">        
            <ename>林黛玉</ename>        
            <age>20</age>        
            <sex></sex>        
            <salary>5000</salary>        
            <empdate>2019-03-14</empdate>    
        </employee>
        <employee eid="3">        
            <ename>杜甫</ename>        
            <age>40</age>        
            <sex></sex>        
            <salary>15000</salary>        
            <empdate>2010-01-01</empdate>    
        </employee>
    </employees>
    

XML約束

  • 在XML技術裡,可以編寫一個文件來約束一個XML文件的書寫規範,這稱之為XML約束

  • 常見的xml約束

    • DTD
    • Schema
  • 作為程式設計師只要掌握兩點

    • 會閱讀
    • 會引入
    • 不用自己編寫

    在這裡插入圖片描述

DTD約束

  • DTD(Document Type Definition),文件型別定義,用來約束XML文件
  • 規定XML文件中元素的名稱,子元素的名稱及順序,元素的屬性等

編寫DTD

  • 開發中,我們不會自己編寫DTD約束文件

  • 通常情況我們都是通過框架提供的DTD約束文件,編寫對應的XML文件。

  • 常見框架使用DTD約束有: Struts2、hibernate等。

  • 建立約束檔案 student.dtd

    <!ELEMENT students (student+) >        
    <!ELEMENT student (name,age,sex)>        
    <!ELEMENT name (#PCDATA)>       
    <!ELEMENT age (#PCDATA)>       
    <!ELEMENT sex (#PCDATA)>        
    <!ATTLIST student number ID #REQUIRED>
    <!-    ELEMENT: 用來定義元素
        students (student+) : 代表根元素 必須是 <students>
        student+ : 根標籤中至少有一個 student子元素, + 代表至少一個
        student (name,age,sex): student 標籤中包含的子元素,按順序出現
        #PCDATA: 是普通文字內容
        ATTLIST: 用來定義屬性        
    		student number ID #REQUIRED       
    		student子元素中 有一個ID屬性叫做 number,是必須填寫的       
    		ID: 唯一 值只能是字母或者下劃線開頭 
    -->
    

引入DTD

  • 引入dtd文件到xml文件中,兩種方式

    • 內部dtd:將約束規則定義在xml文件中
    • 外部dtd:將約束的規則定義在外部的dtd檔案中
  • student.xml

    <?xml version="1.0" encoding="UTF-8" ?> 
    <!DOCTYPE students SYSTEM "student.dtd"> 
    <students>
        <student number="s1">        
            <name>小斌</name>        
            <age>22</age>       
            <sex></sex>
        </student>
        <student number="s2">        
            <name>廣坤</name>        
            <age>55</age>        
            <sex></sex>    
        </student>
    </students>
    

Schema約束

基本概念

  • Schema是新的XML文件約束, 比DTD強大很多,是DTD 替代者
  • Schema本身也是XML文件,但Schema文件的副檔名為xsd,而不是xml
  • Schema 功能更強大,內建多種簡單和複雜的資料型別
  • Schema 支援名稱空間 (一個XML中可以引入多個約束文件)

Schema約束示例

  • student.xsd

    <?xml version="1.0"?> 
    <xsd:schema xmlns="http://www.lagou.com/xml"            			
                xmlns:xsd="http://www.w3.org/2001/XMLSchema"            
                targetNamespace="http://www.lagou.com/xml" elementFormDefault="qualified">
        
        <xsd:element name="students" type="studentsType"/>    
        <xsd:complexType name="studentsType">        
            <xsd:sequence>            
                <xsd:element name="student" type="studentType" minOccurs="0" maxOccurs="unbounded"/>        
            </xsd:sequence>    
        </xsd:complexType>    
        <xsd:complexType name="studentType">       
            <xsd:sequence>           
                <xsd:element name="name" type="xsd:string"/>
                <xsd:element name="age" type="ageType" />           
                <xsd:element name="sex" type="sexType" />        
            </xsd:sequence>        
            <xsd:attribute name="number" type="numberType" use="required"/>   
        </xsd:complexType>   
        <xsd:simpleType name="sexType">     
            <xsd:restriction base="xsd:string">        
                <xsd:enumeration value="male"/>           
                <xsd:enumeration value="female"/>     
            </xsd:restriction> 
        </xsd:simpleType>   
        <xsd:simpleType name="ageType">      
            <xsd:restriction base="xsd:integer">          
                <xsd:minInclusive value="0"/>         
                <xsd:maxInclusive value="200"/>   
            </xsd:restriction>
        </xsd:simpleType>    
        <xsd:simpleType name="numberType">
             <xsd:restriction base="xsd:string">            
                 <xsd:pattern value="hehe_\d{4}"/>       
            </xsd:restriction>    
        </xsd:simpleType> 
    </xsd:schema>
    

XML引入Schema約束

  • xml中引入schema約束的步驟:

    檢視schema文件,找到根元素,在xml中寫出來

    <?xml version="1.0" encoding="UTF-8" ?> 
    <students>  
    </students>
    

    根元素來自哪個名稱空間。使用xmlns指令來宣告

    <?xml version="1.0" encoding="UTF-8" ?> 
    <students   
          xmlns="http://www.lagou.com/xml"
    > 
    </students>
    
    

    引入 w3c的標準名稱空間, 複製即可

    <?xml version="1.0" encoding="UTF-8" ?> 
    <students    
          xmlns="http://www.lagou.com/xml"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
    >
    </students>
    

    引入的名稱空間跟哪個xsd檔案對應

    使用schemaLocation來指定:

    兩個取值:第一個為名稱空間 第二個為xsd檔案的路徑

    <?xml version="1.0" encoding="UTF-8" ?> 
    <students    
          xmlns="http://www.lagou.com/xml"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.lagou.com/xml student.xsd" 
    >
    </students
    

    名稱空間

    指的是一個環境,所用的標籤來自於哪個環境定義的
    

    student.xml

    <?xml version="1.0" encoding="UTF-8" ?> 
    <students    
          xmlns="http://www.lagou.com/xml"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.lagou.com/xml student.xsd" 
    >    
        <student number="hehe_1234">        
            <name>張百萬</name>        
            <age>25</age>        
            <sex>female</sex>    
        </student>
        <student number="hehe_0000">        
            <name>小斌</name>        
            <age>20</age>      
            <sex>male</sex>   
        </student> 
    </students>
    

XML 解析

基本概念

  • 當將資料儲存在XML後,我們就希望通過程式獲得XML的內容
  • 如果我們使用Java基礎所學習的IO知識是可以完成的,不過你需要非常繁瑣的操作才可以完成,且開發中會遇到不同問題(只讀、讀寫)
  • 人們為不同問題提供不同的解析方式,並提交對應的解析器,方便開發人員操作XML

XML解析方式

  • 開發中比較常見的解析方式有兩種,如下:
  • DOM:要求解析器把整個XML文件裝載到記憶體,並解析成一個Document物件
    • 優點:元素與元素之間保留結構關係,故可以進行增刪改查操作
    • 缺點:XML文件過大,可能出現記憶體溢位顯現
  • SAX:是一種速度更快,更有效的方法;它逐行掃描文件,一邊掃描一邊解析;並以事件驅動的方 式進行具體解析,每執行一行,都將觸發對應的事件
    • 優點:佔用記憶體少 處理速度快,可以處理大檔案
    • 缺點:只能讀,逐行後將釋放資源

XML常見的解析器

  • 解析器:就是根據不同的解析方式提供的具體實現。有的解析器操作過於繁瑣,為了方便開發人員, 有提供易於操作的解析開發包
  • JAXP:sun公司提供的解析器,支援DOM和SAX兩種思想
  • DOM4J:一款非常優秀的解析器 , Dom4j是一個易用的、開源的庫,用於XML,XPath和XSLT。 它應用於Java平臺,採用了Java集合框架並完全支援DOM,SAX和JAXP。
  • Jsoup:jsoup 是一款Java 的HTML解析器 ,也可以解析XML
  • PULL:Android內建的XML解析方式,類似SAX

dom4j 的使用

  • 匯入JAR包–dom4j-1.6.1.jar

API介紹

  • 使用核心類SaxReader載入xml文件獲得Document,通過Document 物件獲得文件的根元素,然後就可以操作了

  • 常用API如下:

    SaxReader物件

    • read(…) 載入執行xml文件

    Document物件

    • getRootElement() 獲得根元素

    Element物件

    • elements(…) 獲得指定名稱的所有子元素。可以不指定名稱
    • element(…) 獲得指定名稱的第一個子元素。可以不指定名稱
    • getName() 獲得當前元素的元素名
    • attributeValue(…) 獲得指定屬性名的屬性值
    • elementText(…) 獲得指定名稱子元素的文字值
    • getText() 獲得當前元素的文字內容

讀取xml

  • 讀取xml

    public class TestDOM4j {
        //獲取XML檔案中的 所有的元素名稱(標籤)    
        @Test    
        public void test1() throws DocumentException {
            //1.獲取XML解析物件        
            SAXReader reader = new SAXReader();
            //2.解析XML 獲取 文件物件 document        
            Document document = reader.read("H:\\jdbc_work\\user.xml");
            //3.獲取根元素        
            Element rootElement = document.getRootElement();
            //獲取根元素名稱        
            System.out.println(rootElement.getName());
            //獲取 根元素下的標籤        
            List<Element> elements = rootElement.elements();        
            for (Element element : elements) {            
                System.out.println("根標籤下的子節點: " + element.getName());
                List<Element> eList = element.elements();            
                for (Element e : eList) {                
                    System.out.println("user標籤下的子節點" + e.getName());           
                }
                break;        
            }
        }            
        /**     
         * 獲取具體的節點內容 獲取張百萬的所有資訊     
         */    
        @Test
        public void test2() throws DocumentException {        
            //1.建立XML文件解析物件        
            SAXReader sr = new SAXReader();
            //2.讀取XML獲取到document物件        
            Document document = sr.read("src\\com\\lagou\\xml02\\user.xml");
            //3.獲取根節點        
            Element rootElement = document.getRootElement();
            //4.得到當前節點的 所有子節點        
            List<Element> elements = rootElement.elements();
            //5.獲取第一個子節點        
            Element user = elements.get(0);
            //6.獲取所有資訊        
            String id = user.attributeValue("id");        
            String name = user.elementText("name");        
            String age = user.elementText("age");        
            //使用getText獲取當前元素的文字內容        
            String hobby = user.element("hobby").getText();
            //列印        
            System.out.println(id+" " + name +" " + age +" " + hobby);    
        }
    }
    

xpath的使用

  • 需要匯入 jaxen-1.1-beta-6.jar

XPath基本概念

  • XPath 是一門在 XML 文件中查詢資訊的語言。 可以使用xpath查詢xml中的內容。
  • XPath 的好處
    • 由於DOM4J在解析XML時只能一層一層解析,所以當XML檔案層數過多時使用會很不方便,結合 XPATH就可以直接獲取到某個元素

XPath基本語法介紹

  • 使用dom4j支援xpath的操作的幾種主要形式

    語法說明
    /AAA/DDD/BBB表示一層一層的,AAA下面 DDD下面的BBB
    //BBB表示和這個名稱相同,表示只要名稱是BBB,都得到
    //*所有元素
    BBB[1] , BBB[last()]第一種表示第一個BBB元素, 第二種表示後一個BBB元素
    //BBB[@id]表示只要BBB元素上面有id屬性,都得到
    //BBB[@id=‘b1’]表示元素名稱是BBB,在BBB上面有id屬性,並且id的屬性值是b1

API介紹

  • 常用方法
    • selectSingleNode(query): 查詢和 XPath 查詢匹配的一個節點;引數是Xpath 查詢串。
    • selectNodes(query): 得到的是xml根節點下的所有滿足xpath 的節點; 引數是Xpath 查詢串。
    • Node: 節點物件

Xpath讀取XML

  • 使用selectSingleNode方法 查詢指定節點中的內容

     /*    
      * 1. 使用selectSingleNode方法 查詢指定節點中的內容    
      */    
    @Test    
    public void test1() throws DocumentException {
            
        //1.建立解析器物件        
        SAXReader sr = new SAXReader();
            
        //2.獲取文件物件        
        Document document = sr.read("H:\\jdbc_work\\book.xml");
            
        //3.呼叫 selectSingleNode() 方法,獲取name節點物件        
        Node node1 = document.selectSingleNode("/bookstore/book/name");        
        System.out.println("節點: " + node1.getName());        
        System.out.println("書名: " + node1.getText());
            
        //4.獲取第二本書的名稱        
        Node node2 = document.selectSingleNode("/bookstore/book[2]/name");        
        System.out.println("第二本書的書名為: " + node2.getText());   
    }
    
  • 使用selectSingleNode方法 獲取屬性值,或者屬性值對應的節點

    /*    
     *   2.使用selectSingleNode方法 獲取屬性值,或者屬性值對應的節點    
     */    
    @Test    
    public void test2() throws DocumentException {
            
        //1.建立解析器物件        
        SAXReader sr = new SAXReader();
            
        //2.獲取文件物件        
        Document document = sr.read("H:\\jdbc_work\\book.xml");
            
        //3.獲取第一個book節點的 id屬性的值        
        Node node1 = document.selectSingleNode("/bookstore/book/attribute::id");   
        System.out.println("第一個book的id值為: " + node1.getText());
            
        //4.獲取最後一個book節點的 id屬性的值
         Node node2 = document.selectSingleNode("/bookstore/book[last()]/attribute::id");        
        System.out.println("最後一個book節點的id值為: " + node2.getText());
            
        //5.獲取id屬性值為 book2的 書名        
        Node node3 = document.selectSingleNode("/bookstore/book[@id='book2']");   
        String name = node3.selectSingleNode("name").getText();        
        System.out.println("id為book2的書名是: " + name); 
    }
    
  • 使用 selectNodes()方法 獲取對應名稱的所有節點

    /*    
     *  3.使用 selectNodes()方法 獲取對應名稱的所有節點    
     */    
    @Test    
    public void test3() throws DocumentException {
            
        //1.建立解析器物件        
        SAXReader sr = new SAXReader();
            
        //2.獲取文件物件        
        Document document = sr.read("H:\\jdbc_work\\book.xml");                
        //3.獲取所有節點,列印節點名        
        List<Node> list = document.selectNodes("//*");        
        for (Node node : list) {            
            System.out.println("節點名: " + node.getName());        
        }
            
        //4.獲取所有的書名        
        List<Node> names = document.selectNodes("//name");        
        for (Node name : names) {            
            System.out.println(name.getText());        
        }
            
        //5.獲取指定 id值為book1的節點的所有 內容        
        List<Node> book1 = document.selectNodes("/bookstore/book[@id='book1']//*");        
        for (Node node : book1) {            
            System.out.println(node.getName()+" = " + node.getText());        
        }   
    }
    

JDBC自定義XML

定義配置檔案

  • 建立自定義xml 檔案, 儲存 資料庫連線資訊 jdbc-config.xml

    <?xml version="1.0" encoding="UTF-8" ?> 
    <jdbc>    
        <property name="driverClass">com.mysql.jdbc.Driver</property>    
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/db5? characterEncoding=UTF-8</property>    
        <property name="user">root</property>    
        <property name="password">123456</property>
    </jdbc>
    

編寫工具類(配置式)

  • 編寫工具類 ,使用xpath 讀取資料庫資訊

    public class JDBCUtils {
        //1. 定義字串變數, 記錄獲取連線所需要的資訊    
        public static  String DRIVERNAME;    
        public static  String URL;    
        public static  String USER;    public static  String PASSWORD;
        //2.靜態程式碼塊   
        static {        
            try {            
                //使用 xpath讀取 xml中的配置資訊            
                SAXReader sr = new SAXReader();            
                Document document = sr.read("H:\\workspace01jdbc-config.xml");
                Node node = document.selectSingleNode("/jdbc/property[@name='driverClass']");           
                //System.out.println(node.getText());            
                DRIVERNAME = node.getText();            
                URL = document.selectSingleNode("/jdbc/property[@name='jdbcUrl']").getText();            
                USER = document.selectSingleNode("/jdbc/property[@name='user']").getText();            
                PASSWORD = document.selectSingleNode("/jdbc/property[@name='password']").getText();
                //註冊驅動           
                Class.forName(DRIVERNAME);        
            } catch (Exception e) {            
                e.printStackTrace();        
            }
        }
        //3.獲取連線的靜態方法    
        public static Connection getConnection(){
            try {            
                //獲取連線物件            
                Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
                //返回連線物件            
                return connection;
            } catch (SQLException e) {            
                e.printStackTrace();           
                return null;        
            }   
        }    
    }
    

注:本內容為個人拉勾教育大資料訓練營課程筆記

相關文章