XML基礎知識歸納(通俗易懂)


XML:可擴展標記型語言

隨着json等一些技術的普及,似乎xml的路子越來越窄,雖然xml的一些功能被其他的一些技術代替,但是學習xml還是非常有必要,如果用xml存儲一些大量數據,還是有一定優勢的,就算你不管這些,但是現有的很多框架以及技術的配置文件都存在於xml中,最起碼你得對它的結構以及一些基本用法有一定了解

(一) 基本概述

(1) 概念

XML:Extensible Markup Language:可擴展標記型語言

標記型:使用標簽來操作,html就是一種常見的標記型語言

可擴展:可以自定義標簽,甚至可以用中文寫標簽 Eg:<person></person <張三><張三>

(2) 用途

xml 主要用來存儲數據,體現在作配置文件,或者充當小型數據庫,在網絡中傳輸數據

A:配置文件:例如配置mysql數據庫

前面我們常常書寫 一個 jdbc.properties文件來做配置文件,好處呢就是如果想修改數據庫的信息,不需要修改源代碼,只要修改配置文件就可以了,而xml也可以作為配置文件來使用

url=jdbc:mysql://localhost:3306/db1
user=root
password=root99
driver=com.mysql.jdbc.Driver
<!--例如模擬配置mysql數據庫 只為假設,與前面知識對應,實際配置文件后期會很常見-->
<?xml version="1.0" encoding="UTF-8"?>
<config>
	<dbinfo>
		<dbDriver>com.mysql.jdbc.Driver</dbDriver>
		<dbUrl>jdbc:mysql://localhost:3306/db1</dbUrl>
		<username>root</username>
		<password>root99</password>
</config>

B:充當小型數據庫

我們可以在xml中存儲一些數據,讓它充當一個小型的數據庫

<?xml version="1.0" encoding="UTF-8"?>
<student> 
	<stu> 
    	<id>001</id>  
    	<name>zhangsan</name>  
    	<age>20</age> 
    </stu>  
	<stu> 
    	<id>002</id>  
    	<name>lisi</name>  
    	<age>30</age> 
	</stu>  
</student>

C:傳輸數據

在網絡編程中,我們或多或少接觸過,例如如何實現一個簡單的聊天室,基本原理是這樣的,一個服務器端,多個客戶端,當客戶端1發送數據后,服務器端接收到數據,並且對數據進行一定的審核(是否有非法敏感字)以及格式的處理,再將數據發送到每一個客戶端中

剛開始的時候,我們一般選擇使用字符串直接傳遞內容,但是卻不是很利於程序的后期維護,而使用xml就能對后期程序的維護更加友好

<?xml version="1.0" encoding="UTF-8"?>
<message id="1">
	<sender>賬號1</sender>
	<getter>賬號2</getter>
	<content>發送的信息</content>
    <ip>ip地址</ip>
</message>

(二) xml語法

xml文檔的后綴名為 .xml

(1) 文檔聲明

創建一個xm文件后,第一步就是 必須要有 一個文檔聲明(寫了文檔聲明之后,表寫xml文件的內容)

<?xml version="1.0" encoding="UTF-8"?>
  • version : xml版本,必須寫

  • encoding:xml編碼 常見編碼: GBK、UTF-8、ISO8859-1(不包含中文)

    • 保存時編碼和設置打開時候的編碼需要一致,否則會出現亂碼
  • standalone:是否需要依賴其他文件 yes/no

(2) 標簽的定義

注意事項

  1. 有始有終:<person></peoson>
  2. 合理嵌套:<aa><bb></bb></aa>
  3. 空格和換行均當做內容來解析,所以可能我們需要注意一些縮進的問題

名稱規則

  1. xml 代碼區分大小寫
  2. 名稱不能以數字或者標點符號開始
  3. 不能以 xml、XML、Xml等開頭
  4. 不能包含空格和冒號

(3) 屬性的定義

  1. 一個標簽上可有多個屬性 <person id1="aaa" id2="bbb"></person>
  2. 屬性名稱和值之間使用 = 連接,屬性值用引號包起來(單引號和雙引號都可以)

(4) 注釋

<?xml version="1.0" encoding="UTF-8"?>
<!-- xml注釋 -->

注釋不能嵌套,並且不能放到第一行,第一行必須方式文檔聲明

(5) 特殊字符

如果想在xml中輸入特殊字符,需要對字符進行轉義,因為 < 等會被當做標簽

字符 轉義字符 描述
& &
< < 小於號
> > 大於號
" " 雙引號
' ' 單引號

若多個字符都需要轉義,則可以將這些內容存放到CDATA里面

<![CDATA[ 內容 ]]>

(七) PI指令 (處理指令)

可以在xml設置樣式

<?xml-stylesheet type="text/css" href="css的路徑"?>

(三) xml約束

為什么需要用到約束呢?比如我們現在定義一個 student.xml文件,我們想要在其中保存關於學生的信息,例如id,name,age,但是如果隨便寫入一個標簽 例如 <你好> 從語法的角度上雖然是符合規范的,但是這顯然與我們想要存儲的東西沒有任何關系,所以我們需要通過xml約束技術,約束xml中只能出現的元素

分類

  • DTD:一種相對簡單的約束技術
  • Schema:一種相對復雜的約束技術,看懂即可

DTD約束

(1) dtd的引入方式(三種)

A:使用內部的dtd文件,即將約束規則定義在xml文檔中

<!DOCTYPE 根元素名稱 [
	<!ELEMENT person (name,age)>
	<!ELEMENT name (#PCDATA)>
	<!ELEMENT age (#PCDATA)>
]>

B:引入外部的dtd文件

<!DOCTYPE 根元素名稱 SYSTEM "dtd路徑">

C:使用外部的dtd文件(網絡上的dtd文件)

<!DOCTYPE 根元素 PUBLIC "DTD名稱" "DTD文檔的URL">

例如使用 struts2框架 使用配置文件 所使用 外部的dtd文件

<!DOCTYPE struts PUBLIC   "-//Apache Software Foundation//DTD
Struts Configuration 2.0//EN"    
"http://struts.apache.org/dtds/struts-2.0.dtd">

(2) 使用dtd定義元素

<!ELEMENT 元素名 約束>

A:簡單元素(沒有子元素)

ELEMENT name (#PCDATA)>
	(#PCDATA): 約束name是字符串類型
	EMPTY : 元素為空(沒有內容)
		- <sex></sex>
	ANY:任意

B:復雜元素

<!-- 語法 -->
<!ELEMENT person (id,name,age,)>
	子元素只能出現一次
<!ELEMENT 元素名稱 (子元素)>

<!-- 子元素出現次數 -->
* :一次多或多次
?:零次或一次
* :零次或多次

<!-- 子元素直接使用逗號隔開 -->
	表示元素出現的順序 

<!-- 子元素直接使用 | -->
	表示元素只能出現其中的任意一個

(2) 使用dtd定義屬性

<!-- 語法 -->
<!ATTLIST 元素名稱
	屬性名稱 屬性類型 屬性的約束
>

<!-- 屬性類型 -->	CDATA: 字符串
<!ATTLIST birthday
	ID1 CDATA #REQUIRED
>

<!-- 枚舉 -->
表示只能在一定的范圍內出現值,但是只能每次出現其中的一個,紅綠燈效果
<!ATTLIST age
	ID2 (AA|BB|CC)  #REQUIRED
>

<!-- ID: 值只能是字母或者下划線開頭 -->
<!ATTLIST name 
	ID3 ID   #REQUIRED
>

<!-- 屬性的約束 -->
#REQUIRED:屬性必須存在
#IMPLIED:屬性可有可無
#FIXED: 表示一個固定值 #FIXED "AAA"
	屬性的值必須是設置的這個固定值
		<!ATTLIST sex
			ID4 CDATA #FIXED "ABC"
		>

直接值
	不寫屬性,使用直接值
	寫了屬性,使用設置那個值
		<!ATTLIST school
			ID5 CDATA "WWW"
		>

Schema約束

schema 符合 xml 的語法,一個 xml 中可以有多個 schema ,多個 schema 使用名稱空間區分(類似於java包名)dtd 里面有PCDATA類型,但是在 schema 里面可以支持更多的數據類型

后綴名:xsd

引入:
填寫xml文檔的根元素

引入xsi前綴.  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	表示xml文件是一個約束文件
	
引入xsd文件命名空間.  xsi:schemaLocation="http://www.bwh.cn/xml  student.xsd"
	使用一個使用schema約束文件,直接通過這個地址引入約束文件
	  通常使用一個url地址防止重名
	  
為每一個xsd約束聲明一個前綴,作為標識  xmlns="http://www.bwh.cn/xml" 

(1) 看xml中有多少個元素

<element>

(2) 看簡單元素和復雜元素

<element name="person">
<complexType>
<sequence>
	<element name="name" type="string"></element>
					<element name="age" type="int"></element>
</sequence>
</complexType>
</element>

(3) 被約束文件里面引入約束文件

<person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.bwh.cn/20151111"
xsi:schemaLocation="http://www.bwh.cn/20151111 1.xsd">

			xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
				-- 表示xml是一個被約束文件
			xmlns="http://www.bwh.cn/20151111"
				-- 是約束文檔里面 targetNamespace
			xsi:schemaLocation="http://www.bwh.cn/20151111 1.xsd">
				-- targetNamespace 空格  約束文檔的地址路徑

可以約束屬性

A: <sequence>:表示元素的出現的順序
B: <all>: 元素只能出現一次
C: <choice>:元素只能出現其中的一個
D: maxOccurs="unbounded": 表示元素的出現的次數
E: <any></any>:表示任意元素

寫在復雜元素里面
寫在 </complexType>之前

--
<attribute name="id1" type="int" use="required"></attribute>
	- name: 屬性名稱
	- type:屬性類型 int stirng
	- use:屬性是否必須出現 required

(四) xml的解析

很簡單的理解解析:有一個xml,在其中讀取出需要的數據

(1) 解析方式 dom和sax

DOM:根據xml的層級結構在內存中分配一個樹形結構,把xml的標簽,屬性和文本都封裝成對象,一次性加載進內存

  • 優點:操作方便,很容易實現增刪改操作

  • 缺點:占內存,有造成內存溢出風險

SAX:采用事件驅動,邊讀邊解析,解析到某一個對象,返回對象名稱

  • 優點:不占內存
  • 缺點:只能讀取,不能實現增刪改操作

(2) 解析器

想要解析xml,我們必須了解解析器,不同的公司和組織,提供了針對dom和sax方式的解析器,通過api方式提供 (今天着重講解兩種比較常用的)

  1. jaxp:sun公司所提供針對dom和sax的解析器,效率略低
  2. dim4j:非常優秀的解析器,在實際開發中比較常用
  3. jdom:jdom組織所提供的針對dom和sax解析器
  4. jsoup:jsoup 是一款Java 的HTML解析器,可直接解析某個URL地址、HTML文本內容。它提供了一套非常省力的API,可通過DOM,CSS以及類似於jQuery的操作方法來取出和操作數據。
  5. Pull:Android操作系統內置的解析器,sax方式的

(3) 使用 dom4 操作 xml

注意:下面的所有java代碼中,由於我的代碼寫在Module中,所以路徑加了名字,若直接創建的是項目,只寫src/s1.xml即可

<?xml version="1.0" encoding="UTF-8"?>
<student>
    <stu id1="love">
        <name>zhangsan</name>
        <age>20</age>
    </stu>
    <stu>
        <name>lisi</name>
        <age>30</age>
    </stu>
</student>

※ 使用dom4j實現查詢xml操作

(一)查詢所有name元素里面的值

package cn.ideal.xml.dom4j;

/*
   1、創建解析器
   2、得到document
   3、得到根節點  getRootElement() 返回Element
   4、得到所有的p1標簽
      * elements("p1") 返回list集合
      * 遍歷list得到每一個p1
   5、得到name
      * 在p1下面執行 element("name")方法 返回Element
   6、得到name里面的值
      * getText方法得到值
*/

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.util.List;

public class TestDom4j1 {
    //查詢xml中所有name元素的值
    public static void main(String[] args) throws DocumentException {
        //創建解析器
        SAXReader saxReader = new SAXReader();
        //得到document
        Document document = saxReader.read("code-04_xml/src/s1.xml");
        //得到根節點
        Element rootElement = document.getRootElement();
        //得到stu
        List<Element> list = rootElement.elements("stu");

        //遍歷list
        for (Element element : list) {
            //element是每一個元素
            //得到name里面的值
            Element name1 = element.element("name");
            //得到name里面的值
            String s = name1.getText();
            System.out.println(s);
        }
    }
}
//運行結果
zhangsan
lisi

(二)查詢第一個name元素的值

package cn.ideal.xml.dom4j;

/*
    1、創建解析器
    2、得到document
    3、得到根節點
    4、得到第一個stu元素
        element("stu")方法 返回Element
    5、得到p1下面的name元素
        element("name")方法 返回Element
    6、得到name元素里面的值
        getText方法
 */

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class TestDom4j2 {
    public static void main(String[] args) throws DocumentException {
        //創建解析器
        SAXReader saxReader = new SAXReader();
        //得到document對象
        Document document = saxReader.read("code-04_xml/src/s1.xml");
        //得到根節點
        Element rootElement = document.getRootElement();
        //得到第一個stu元素
        Element stu = rootElement.element("stu");
        //得到stu下面的name元素
        Element name1 = stu.element("name");
        //得到name的值
        String s1 = name1.getText();
        System.out.println(s1);
    }
}

//運行結果
zhangsan

(三)獲取第二個name元素的值

package cn.ideal.xml.dom4j;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.util.List;

/*
    1、創建解析器
    2、得到document
    3、得到根節點
    4、得到所有的stu
        返回 list集合
    5、遍歷得到第二個stu
        使用list下標得到 get方法,集合的下標從 0 開始,想要得到第二個值,下標寫 1
    6、得到第二個p1下面的name
        element("name")方法 返回Element
    7、得到name的值
        getText方法
 */
public class TestDom4j3 {
    public static void main(String[] args) throws DocumentException {
        //創建解析器
        SAXReader saxReader = new SAXReader();
        //得到document
        Document document = saxReader.read("code-04_xml/src/s1.xml");
        //得到根節點
        Element rootElement = document.getRootElement();
        //得到所有stu
        List<Element> list = rootElement.elements("stu");
        //得到第二個stu
        Element stu2 = list.get(1);
        //得到stu下的name
        Element name2 = stu2.element("name");
        //得到name里面的值
        String s2 = name2.getText();
        System.out.println(s2);
    }
}

※ 使用dom4j實現添加操作

**(一)在第一個p1標簽末尾添加一個元素 **<sex>male</sex>

package cn.ideal.xml.dom4j;

import org.dom4j.Document;

import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.FileOutputStream;


/*
    1、創建解析器
    2、得到document
    3、得到根節點

    4、獲取到第一個p1
        使用element方法
    5、在p1下面添加元素
        在p1上面直接使用 addElement("標簽名稱")方法 返回一個Element

    6、在添加完成之后的元素下面添加文本
       在sex上直接使用 setText("文本內容")方法
    7、回寫xml
        格式化 OutputFormat,使用 createPrettyPrint方法,表示一個漂亮的格式
        使用類XMLWriter 直接new 這個類 ,傳遞兩個參數
        第一個參數是xml文件路徑 new FileOutputStream("路徑")
        第二個參數是格式化類的值
*/
public class TestDom4j4 {
    public static void main(String[] args) throws Exception {
        //創建解析器
        SAXReader saxReader = new SAXReader();
        //得到document
        Document document = saxReader.read("code-04_xml/src/s1.xml");
        //得到根節點
        Element rootElement = document.getRootElement();
        //得到第一個stu元素
        Element stu = rootElement.element("stu");
        //在stu下面直接添加元素
        Element sex1 = stu.addElement("sex");
        //在sex下面添加文本
        sex1.setText("male");

        //回寫xml
        OutputFormat prettyPrint = OutputFormat.createPrettyPrint();//有縮進效果
        XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("code-04_xml/src/s1.xml"), prettyPrint);
        xmlWriter.write(document);
    }
}

寫一個工具類,簡化操作

封裝方法的操作,可以省略創建解析器 得到document 以及回寫xml的方法,把傳遞的文件路徑,封裝成一個常量

好處:可以提高開發速度,可以提交代碼可維護性

比如想要修改文件路徑(名稱),這個時候只需要修改常量的值就可以了,其他代碼不需要做任何改變

package cn.ideal.xml.utils;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.FileOutputStream;
import java.io.IOException;

public class Dom4jUtils {
    public static final String PATH = "code-04_xml/src/s1.xml";

    //返回document
    public static Document getDocument(String path) {
        //創建解析器
        SAXReader saxReader = new SAXReader();
        //得到document
        try {
            Document document = saxReader.read(path);
            return document;
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return null;
    }

    //回寫xml的方法
    public static void xmlWriters(String path, Document document) {
        try {
            OutputFormat prettyPrint = OutputFormat.createPrettyPrint();//有縮進效果
            XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(path), prettyPrint);
            xmlWriter.write(document);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

我們上面執行添加操作的代碼就可以簡化為

package cn.ideal.xml.dom4j;

import cn.ideal.xml.utils.Dom4jUtils;
import org.dom4j.Document;
import org.dom4j.Element;


public class TestDom4j5 {
    public static void main(String[] args) throws Exception {

        Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
        //得到根節點
        Element rootElement = document.getRootElement();
        //得到第一個stu元素
        Element stu = rootElement.element("stu");
        //在stu下面直接添加元素
        Element sex1 = stu.addElement("sex");
        //在sex下面添加文本
        sex1.setText("male");

        //回寫xml
        Dom4jUtils.xmlWriters(Dom4jUtils.PATH, document);
    }
}

**(二)使用dom4j實現在特定位置添加元素 **

在第一個stu下面的name標簽前添加 <id>001</id>

package cn.ideal.xml.dom4j;

import cn.ideal.xml.utils.Dom4jUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import java.util.List;

/*
    1、創建解析器
    2、得到document
    3、得到根節點
    4、獲取到第一個p1

    5、獲取p1下面的所有的元素
           ** elements()方法 返回 list集合

        ** 使用list里面的方法,在特定位置添加元素
       ** 首先創建元素 在元素下面創建文本
              - 使用DocumentHelper類方法createElement創建標簽
              - 把文本添加到標簽下面 使用 setText("文本內容")方法

         ** list集合里面的 add(int index, E element)
           - 第一個參數是 位置 下標,從0開始
           - 第二個參數是 要添加的元素
      6、回寫xml
*/
public class TestDom4j6 {
    //在第一個stu下面的name標簽前添加<id>001</id>
    public static void main(String[] args) {
        Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
        //得到根節點
        Element rootElement = document.getRootElement();
        //得到第一個stu元素
        Element stu = rootElement.element("stu");
        //獲取stu下全部元素
        List<Element> list = stu.elements();
        //創建元素
        Element id = DocumentHelper.createElement("id");
        //在id下面創建文本
        id.setText("001");
        //在特定位置添加
        list.add(0, id);

        Dom4jUtils.xmlWriters(Dom4jUtils.PATH, document);
    }
}

**(三)使用dom4j實現修改節點的操作 **

修改第一個p1下面的age元素的值為18

package cn.ideal.xml.dom4j;
/*
    1、得到document
   	2、得到根節點,然后再得到第一個p1元素
   	3、得到第一個p1下面的age
      element("")方法
   	4、修改值是 30
       使用setText("文本內容")方法
   	5、回寫xml
*/

import cn.ideal.xml.utils.Dom4jUtils;
import org.dom4j.Document;
import org.dom4j.Element;

public class TestDom4j7 {
    public static void main(String[] args) {
        //得到document
        Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
        //得到根節點
        Element rootElement = document.getRootElement();
        //得到第一個stu元素
        Element stu = rootElement.element("stu");
        //得到第一個stu下面的age
        Element age = stu.element("age");
        age.setText("18");
        //回寫xml
        Dom4jUtils.xmlWriters(Dom4jUtils.PATH, document);
    }
}

※ 使用dom4j實現刪除節點的操作

package cn.ideal.xml.dom4j;

import cn.ideal.xml.utils.Dom4jUtils;
import org.dom4j.Document;
import org.dom4j.Element;

public class TestDom4j8 {
    public static void main(String[] args) {
        //得到document
        Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
        //得到根節點
        Element rootElement = document.getRootElement();
        //得到第一個stu元素
        Element stu = rootElement.element("stu");
        //得到第一個stu下面的age
        Element id = stu.element("id");

        stu.remove(id);
        //回寫xml
        Dom4jUtils.xmlWriters(Dom4jUtils.PATH, document);
    }
}

使用dom4j獲取屬性的操作

package cn.ideal.xml.dom4j;

import cn.ideal.xml.utils.Dom4jUtils;
import org.dom4j.Document;
import org.dom4j.Element;

public class TestDom4j9 {
    public static void main(String[] args) {
        //得到document
        Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
        //得到根節點
        Element rootElement = document.getRootElement();
        //得到第一個stu元素
        Element stu = rootElement.element("stu");
        //得到stu里面的屬性值
        String value = stu.attributeValue("id1");
        System.out.println(value);
    }
}

(4) 使用dom4j支持xpath具體操作

XPath即為XML路徑語言(XML Path Language),它是一種用來確定XML文檔中某部分位置的語言

默認的情況下,dom4j不支持xpath

如果想用,需要引入支持xpath的jar包,使用 jaxen-1.1-beta-6.jar

第一種形式
	/AAA/CCC/BBB: 表示一層一層的,AAA下面CCC下面的BBB
第二種形式
	//BBB: 表示和這個名稱相同,表示只要名稱是BBB,都得到
第三種形式
	/*: 所有元素
第四種形式
	BBB[1]: 表示第一個BBB元素
	BBB[last()]:表示最后一個BBB元素
第五種形式
	//BBB[@id]: 表示只要BBB元素上面有id屬性,都得到
第六種形式
	//BBB[@id='b1'] 表示元素名稱是BBB,在BBB上面有id屬性,並且id的屬性值是b1

dom4j里面提供了兩個方法,用來支持xpath

//獲取多個節點
selectNodes("xpath表達式")

//獲取一個節點
selectSingleNode("xpath表達式")

(一)使用xpath實現:查詢xml中所有name元素的值

package cn.ideal.xml.dom4j.xpath;

import cn.ideal.xml.utils.Dom4jUtils;
import org.dom4j.Document;
import org.dom4j.Node;

import java.util.List;

public class TestDom4jXpath1 {
    //查詢xml中所有name元素的值
    public static void main(String[] args) {
        //得到document
        Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
        //獲取所有name元素
        List<Node> list = document.selectNodes("//name");
        //遍歷list集合
        for (Node node : list) {
            //node是每一個name元素
            //得到name元素里面的值
            String s = node.getText();
            System.out.println(s);
        }
    }
}

(二)使用xpath實現:獲取第一個stu下面的name的值

package cn.ideal.xml.dom4j.xpath;

import cn.ideal.xml.utils.Dom4jUtils;
import org.dom4j.Document;
import org.dom4j.Node;

public class TestDom4jXpath2 {
    public static void main(String[] args) {
        //得到document
        Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
        Node name1 = document.selectSingleNode("//stu[@id1='love']/name");
        //得到name里面的值
        String s1 = name1.getText();
        System.out.println(s1);
    }
}

(4) 使用 Jsoup 操作 xml

package cn.ideal.xml.jsoup;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;
import java.io.IOException;

public class JsoupDemo1 {
    public static void main(String[] args) throws IOException {
        //獲取Documnet對象
        //通過類加載器,獲取student.xml的path
        String path = JsoupDemo1.class.getClassLoader().getResource("student.xml").getPath();
        //解析xml文檔,加載文檔進內存,獲取dom樹 --> Document
        Document document = Jsoup.parse(new File(path), "utf-8");
        //獲取元素對象 Element
        Elements elements = document.getElementsByTag("name");

        //獲取第一個name
        Element element = elements.get(0);
        //獲取數據
        String name = element.text();
        System.out.println(name);
    }
}

對上述常用對象的解釋

1. Jsoup:工具類:可以解析html或xml文檔,返回Document

parse:

//解析xml或html文件
parse (File in, String charsetName)

//解析xml或html字符串
parse (String html)

//通過網絡路徑獲取指定的html或xml
parse (URL url, int timeoutMillis)

2. Document:文檔對象:代表內存中的dom樹

A:獲取Element對象

//根據id屬性值獲取唯一的element對象
getElementById (String id)

//根據標簽名稱獲取元素對象集合
getElementsByTag (String tagName)

//根據屬性名稱獲取元素對象集合
getElementsByAttribute (String key)

//根據對應的屬性名和屬性值獲取元素對象集合
getElementsByAttributeValue (String key, String value)

3. Elements:元素Element對象的集合。可以近似的認為 ArrayList<Element>

A:獲取Element對象,同2中

B:獲取屬性值

String attr(String key):根據屬性名稱獲取屬性值

C:獲取文本內容

//獲取文本內容
String text()

//獲取標簽體的所有內容
String html()

兩種更加快捷的查詢方式

selector:選擇器

Elements select(String cssQuery)
//具體語法,看文檔格式
<?xml version="1.0" encoding="UTF-8"?>
<student>
    <stu number="stu_001">
        <name id="ideal">zhangsan</name>
        <age>18</age>
    </stu>
    <stu number="stu_002">
        <name>lisi</name>
        <age>30</age>
    </stu>
</student>
package cn.ideal.xml.jsoup;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import java.io.File;
import java.io.IOException;

public class SelectorDemo {
    public static void main(String[] args) throws IOException {
        //獲取Documnet對象
        //通過類加載器,獲取student.xml的path
        String path = JsoupDemo1.class.getClassLoader().getResource("student.xml").getPath();
        //解析xml文檔,加載文檔進內存,獲取dom樹 --> Document
        Document document = Jsoup.parse(new File(path), "utf-8");

        //查詢name標簽
        Elements elements1 = document.select("name");
        System.out.println(elements1);

        System.out.println("--------------");

        //查詢id值為 stu_001
        Elements elements2 = document.select("#ideal");
        System.out.println(elements2);

        System.out.println("--------------");

        Elements elements3 = document.select("stu[number='stu_001']");
        System.out.println(elements3);

    }
}

//運行結果
<name id="ideal">
 zhangsan
</name>
<name>
 lisi
</name>
--------------
<name id="ideal">
 zhangsan
</name>
--------------
<stu number="stu_001"> 
 <name id="ideal">
  zhangsan
 </name> 
 <age>
  18
 </age> 
</stu>

XPath

package cn.ideal.xml.jsoup;

import cn.wanghaomiao.xpath.model.JXDocument;
import cn.wanghaomiao.xpath.model.JXNode;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import java.io.File;
import java.util.List;

public class XpathDemo {
    public static void main(String[] args) throws Exception {
//獲取Documnet對象
        //通過類加載器,獲取student.xml的path
        String path = JsoupDemo1.class.getClassLoader().getResource("student.xml").getPath();
        //解析xml文檔,加載文檔進內存,獲取dom樹 --> Document
        Document document = Jsoup.parse(new File(path), "utf-8");

        //創建JXDocument對象
        JXDocument jxDocument = new JXDocument(document);

        //結合xpath語法查詢
        List<JXNode> jxNodes = jxDocument.selN("//stu");
        for (JXNode jxNode : jxNodes) {
            System.out.println(jxNode);
        }
    }
}

//運行結果
<stu number="stu_001"> 
 <name id="ideal">
  zhangsan
 </name> 
 <age>
  18
 </age> 
</stu>
<stu number="stu_002"> 
 <name>
  lisi
 </name> 
 <age>
  30
 </age> 
</stu>
//查詢stu標簽下的name標簽
List<JXNode> jxNodes = jxDocument.selN("//student/name");

//查詢stu標簽下帶有id屬性且屬性值ideal的name標簽
List<JXNode> jxNodes = jxDocument.selN("//stu/name[@id='ideal']");

結尾:

如果內容中有什么不足,或者錯誤的地方,歡迎大家給我留言提出意見, 蟹蟹大家 !_

如果能幫到你的話,那就來關注我吧!(系列文章均會在公眾號第一時間更新)

在這里的我們素不相識,卻都在為了自己的夢而努力 ❤

一個堅持推送原創Java技術的公眾號:理想二旬不止


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM