Java篇-XML書寫與解析

一 : XML 簡(jiǎn)介

XML (Extensible Markup Language) ,可擴(kuò)展標(biāo)記語(yǔ)言,與HTML較為相似.HTML中的元素是固定的,XML的標(biāo)簽是可以用戶自定義的. 現(xiàn)在通常用JSON作為數(shù)據(jù)間的傳輸,XML則作為配置文件.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://www.example.org/web-app_2_5" 
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.example.org/web-app_2_5 web-app_2_5.xsd"
            version="2.5">
    <servlet>
        <servlet-name>
            hello雪芙
        </servlet-name>
        <servlet-class>
            111111
        </servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>
            hellow雪瑤
        </servlet-name>
        <url-pattern>
            2222
        </url-pattern>
    </servlet-mapping>
</web-app>

二 : XML語(yǔ)法與結(jié)構(gòu)

文檔聲明

  • 文檔聲明以<? xml開頭, 以?>結(jié)束
  • 文檔聲明必須從文檔的0行0列位置開始:

也就是說(shuō)我們編寫XML文件時(shí)候必須以左上角為起始點(diǎn),不能留任何間隔.

元素

  • 元素有結(jié)構(gòu)開始標(biāo)簽,元素體,結(jié)束標(biāo)簽組成, <servlet-name> hello雪芙 </servlet-name>
  • 元素體 : 元素體可以是元素,也可以說(shuō)文本,也就是說(shuō)元素之間是可以嵌套的, 如 : <world> <me> life</me> </world>
  • 空元素 : 空元素只有開始標(biāo)簽,而沒有結(jié)束標(biāo)簽,但元素必須自己閉合,<a/>
  • 元素命名規(guī)范 :
  1. 區(qū)分大小寫
  2. 不能使用空格,冒號(hào).
  3. 有且只有一個(gè)根元素.

屬性

  1. 屬性是元素的一部分,必須出現(xiàn)在元素的開始標(biāo)簽中
  2. 屬性的定義格式 : 屬性名 = '屬性值',其中屬性值必須使用單引號(hào)或雙引號(hào).
  3. 一個(gè)元素中可以有多個(gè)屬性,但屬性名不能相同
  4. 屬性名不能使用空格,冒號(hào)等特殊字符,且必須以字母開頭

注釋

注釋與HTML的相同 ,command+/快捷鍵, ,注釋內(nèi)容會(huì)被解析器忽略!

轉(zhuǎn)義字符

由于很多符號(hào)已經(jīng)被XML 文檔結(jié)構(gòu)所使用,所以在元素體或?qū)傩灾抵邢胍褂眠@些符號(hào)就必須使用轉(zhuǎn)義字符.

字符 字符引用(十進(jìn)制代碼) 字符引用(十六進(jìn)制代碼) 預(yù)定義實(shí)體引用
< &#60 &#x3c &lt
> &#62 &#x3e &gt
" &#34 &#x22 &quot
' &#39 &#x27 &apos
& &#38 &#x26 &amp

CDATA

當(dāng)有大量轉(zhuǎn)義字符,或者圖省事,可以使用CDTA,不僅能使XML可讀性提高,而且很簡(jiǎn)單.

<?xml version = "1.0"?>
<hellow version = "1" id= "1">
    <b>
        <![CDATA[
            dfsdfsdf
        ]]>
    </b>
</hellow>

在CDATA段中不能包含"]]>",即CDTA段的結(jié)束定界符.

三 : XML常見約束

( 一 ) DTD約束

DTD( Document Type Definition) ,文檔類型定義,用來(lái)約束XML文檔,規(guī)定XML文檔中元素的名稱,子元素的名稱及順序,元素屬性等.開發(fā)中我們幾乎不會(huì)編寫DTD約束文檔,都是使用框架提供的DTD約束文檔.

常見框架使用DTD約束有 : struts2,hibernate

<!ELEMENT web-app (servlet*,servlet-mapping* , welcome-file-list?) >
<!ELEMENT servlet (servlet-name,description?,(servlet-class|jsp-file))>
<!ELEMENT servlet-mapping (servlet-name,url-pattern+) >
<!ELEMENT servlet-name (#PCDATA)>
<!ELEMENT servlet-class (#PCDATA)>
<!ELEMENT url-pattern (#PCDATA)>
<!ELEMENT description (#PCDATA)>
<!ELEMENT jsp-file (#PCDATA)>

<!ELEMENT welcome-file-list (welcome-file+)>
<!ELEMENT welcome-file (#PCDATA)>
<!ATTLIST web-app version CDATA #IMPLIED>

使用DTD文檔的方法.
①導(dǎo)入.dtd約束文檔,拷貝到相同目錄下
②拷貝DTD文檔開始處,拷貝需要的文檔聲明,復(fù)制到自己的XML配置文件里.
③根據(jù)提示編寫XML內(nèi)容.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app SYSTEM "web-app_2_3.dtd">
<web-app version = "1.0">
    <servlet>
        <servlet-name>
        </servlet-name>
    
        <servlet-class>
        </servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>
            aaa
        </servlet-name>
        
        <url-pattern>
        </url-pattern>
    </servlet-mapping>
    
    <welcome-file-list>
        <welcome-file>
        </welcome-file>
    </welcome-file-list>
</web-app>

XML引入DTD的三種聲明方式 :
①內(nèi)部DTD,在XML文檔內(nèi)部嵌入DTD,只對(duì)當(dāng)前XML有效.
②外部DTD,本地DTD,DTD文檔在本地系統(tǒng)上,內(nèi)部自己項(xiàng)目使用,關(guān)鍵字 : SYSTEM
③外部DTD,公共DTD,DTD文檔在網(wǎng)絡(luò)上,一般都有框架提供關(guān)鍵字 : PUBLIC

( 二 )Schema約束

與DTD一樣也是XML的文檔約束,相比于DTD,功能更為強(qiáng)大,是DTD替代者,后綴名為xsd,支持名稱空間
常見框架使用schema的有Spring

<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://www.example.org/web-app_2_5"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:tns="http://www.example.org/web-app_2_5" 
    elementFormDefault="qualified">
    
    <xsd:element name="web-app">
        <xsd:complexType>
            <xsd:choice minOccurs="0" maxOccurs="unbounded">
                <xsd:element name="servlet">
                    <xsd:complexType>
                        <xsd:sequence>
                            <xsd:element name="servlet-name"></xsd:element>
                            <xsd:element name="servlet-class"></xsd:element>
                        </xsd:sequence>
                    </xsd:complexType>
                </xsd:element>
                <xsd:element name="servlet-mapping">
                    <xsd:complexType>
                        <xsd:sequence>
                            <xsd:element name="servlet-name"></xsd:element>
                            <xsd:element name="url-pattern" maxOccurs="unbounded"></xsd:element>
                        </xsd:sequence>
                    </xsd:complexType>
                </xsd:element>
                <xsd:element name="welcome-file-list">
                    <xsd:complexType>
                        <xsd:sequence>
                            <xsd:element name="welcome-file" maxOccurs="unbounded"></xsd:element>
                        </xsd:sequence>
                    </xsd:complexType>
                </xsd:element>
            </xsd:choice>
            <xsd:attribute name="version" type="double" use="optional"></xsd:attribute>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

Schema約束使用方式與DTD使用方式一樣.

命名空間

如果一個(gè)XML文檔使用多個(gè)Schema文件,多個(gè)文件中定義同名元素時(shí),就會(huì)出現(xiàn)名字沖突,命名空間就是用來(lái)處理元素和屬性的名稱沖突問題的,與Java中的包是同一用途.

在.xsd文件中

<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" ...>

表示自定義schema約束文檔引用官方文檔作為顯示命名空間,如果要使用官方提供的元素或?qū)傩?必須使用xsd前綴.

 targetNamespace="http://www.example.org/web-app_2_5"

表示給當(dāng)前自定義約束文檔進(jìn)行起名,提供給xml文檔使用

    xmlns:tns="http://www.example.org/web-app_2_5" 

要是有改schema文件元素,就要在前面加前綴tns

在根據(jù)schema文檔寫的XML文件中

<web-app xmlns="http://www.example.org/web-app_2_5" 
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.example.org/web-app_2_5 web-app_2_5.xsd"
            version="2.5">
    <servlet>
        <servlet-name>
            hello雪芙
        </servlet-name>
        <servlet-class>
            111111
        </servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>
            hellow雪瑤
        </servlet-name>
        <url-pattern>
            2222
        </url-pattern>
    </servlet-mapping>
</web-app>
<web-app xmlns="http://www.example.org/web-app_2_5" 

表示XML文檔引用自定義約束文檔,作為默認(rèn)命名空間.

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

表示是一個(gè)schema實(shí)例文檔,引入w3c實(shí)例文檔.

xsi:schemaLocation="http://www.example.org/web-app_2_5 web-app_2_5.xsd"

表示確定當(dāng)前xml使用到的schema文檔的位置,名稱 與 路徑稱為出現(xiàn)

四 : XML解析

  • 解析方式

DOM : 要求解析器把整個(gè)XML文檔裝載到內(nèi)存,并解析成一個(gè)Document對(duì)象.
使用DOM解析能使元素與元素之間保留結(jié)構(gòu)關(guān)系,故可以進(jìn)行增刪改查操作,但是XML文檔過(guò)大,可能出現(xiàn)內(nèi)存溢出現(xiàn)象.

SAX : 是一種速度更快,更有效的方法,它逐行掃描文檔,一邊掃描一邊解析,并以事件驅(qū)動(dòng)的方式進(jìn)行具體解析,每執(zhí)一行,都將觸發(fā)對(duì)應(yīng)的事件.
處理速度快,可處理大文件,但是只能讀沒然后逐行釋放資源.

PULL : Android內(nèi)置的XML解析方式,類似SAX

  • 常見的解析開發(fā)包 :

① JAXP : sun公司提供支持DOM和SAX開發(fā)包
② jsoup : 一種處理HTML特定解析開發(fā)包
③ dom4j : 比較常用的解析開發(fā)包,hibernate底層采用
④ JDom : dom4j兄弟

  • DOM解析原理

XML DOM 與HTML DOM 類似,將整個(gè)XML加載到內(nèi)存,生成DOM樹,并獲得一個(gè)Document對(duì)象,通過(guò)Document對(duì)象就可以對(duì)DOM進(jìn)行操作

  • dom4j API使用

①導(dǎo)入jar包
② XML文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://www.example.org/web-app_2_5" 
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.example.org/web-app_2_5 web-app_2_5.xsd"
            version="2.5">
        
    <servlet>
        <servlet-name>
            MyServlet1
        </servlet-name>
        <servlet-class>
        
            com.TianTianBayby.web.servlet1.MyServlet1
            
        </servlet-class>
    
    </servlet>
    <servlet-mapping>
        <servlet-name>
            MyServlet1
        </servlet-name>
        <url-pattern>
            /myServlet1
        </url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>
            MyServlet2
        </servlet-name>
        <servlet-class>
        
         com.TianTianBayby.web.servlet1.MyServlet2
         
        </servlet-class>
    
    </servlet>
    <servlet-mapping>
        <servlet-name>
            MyServlet2
        </servlet-name>
        <url-pattern>
            /myServlet2
        </url-pattern>
    </servlet-mapping>
</web-app>

③ dom4j 使用核心類SaxReader加載xml文檔獲得Document,
通過(guò)Document對(duì)象獲得文檔

public void testMyServlet() throws Exception{
        
        //1.創(chuàng)建解析器對(duì)象
        SAXReader saxReader = new SAXReader();
        //2.使用解析器加載web.xml文件得到document對(duì)象
        Document document = saxReader.read("src/com/TianTianBayby/web/servlet1/web.xml");
        //3.獲取根元素節(jié)點(diǎn)
        Element rootElement = document.getRootElement();
        
        //4.根據(jù)元素名稱獲取子元素節(jié)點(diǎn)
        Element servletElement = rootElement.element("servlet");
        
        //5.根據(jù)元素名稱獲取servlet-class的文本節(jié)點(diǎn)
        String servletClass = servletElement.element("servlet-class").getText();

        //6.通過(guò)類全名獲取字節(jié)碼文件
        Class clazz = Class.forName(servletClass.trim());
        
//     //7創(chuàng)建實(shí)例對(duì)象
       IMServlet my = (IMServlet)clazz.newInstance();
       my.init();
       my.service();
       my.destory();
        
    }
}
MyServlet1創(chuàng)建
MyServlet1服務(wù)
MyServlet1銷毀
  • dom4j 常用方法

① SaxReader對(duì)象,
read("..") 加載執(zhí)行xml文檔
② Document對(duì)象
getRootElement()獲得根元素
③ Element對(duì)象
elements("..")獲得指定名稱的所有子元素,可以不指定名稱
element("..")獲得指定名稱的第一個(gè)子元素,可以不指定名稱
getName()獲得當(dāng)前元素的元素名
attributeValue("..")獲得指定屬性名的屬性值
elementText("..")獲得指定名稱子元素的文本值
getText()獲得當(dāng)前元素的文本內(nèi)容

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末闷叉,一起剝皮案震驚了整個(gè)濱河市冠绢,隨后出現(xiàn)的幾起案子纬向,更是在濱河造成了極大的恐慌外构,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,919評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓮恭,死亡現(xiàn)場(chǎng)離奇詭異宇色,居然都是意外死亡仓技,警方通過(guò)查閱死者的電腦和手機(jī)讶请,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門祷嘶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事论巍≈蛞辏” “怎么了?”我有些...
    開封第一講書人閱讀 163,316評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵嘉汰,是天一觀的道長(zhǎng)丹禀。 經(jīng)常有香客問我,道長(zhǎng)鞋怀,這世上最難降的妖魔是什么双泪? 我笑而不...
    開封第一講書人閱讀 58,294評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮密似,結(jié)果婚禮上攒读,老公的妹妹穿的比我還像新娘。我一直安慰自己辛友,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評(píng)論 6 390
  • 文/花漫 我一把揭開白布剪返。 她就那樣靜靜地躺著废累,像睡著了一般。 火紅的嫁衣襯著肌膚如雪脱盲。 梳的紋絲不亂的頭發(fā)上邑滨,一...
    開封第一講書人閱讀 51,245評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音钱反,去河邊找鬼掖看。 笑死,一個(gè)胖子當(dāng)著我的面吹牛面哥,可吹牛的內(nèi)容都是我干的哎壳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,120評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼尚卫,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼归榕!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起吱涉,我...
    開封第一講書人閱讀 38,964評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤刹泄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后怎爵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體特石,經(jīng)...
    沈念sama閱讀 45,376評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評(píng)論 2 333
  • 正文 我和宋清朗相戀三年鳖链,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了姆蘸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,764評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖乞旦,靈堂內(nèi)的尸體忽然破棺而出贼穆,到底是詐尸還是另有隱情,我是刑警寧澤兰粉,帶...
    沈念sama閱讀 35,460評(píng)論 5 344
  • 正文 年R本政府宣布故痊,位于F島的核電站,受9級(jí)特大地震影響玖姑,放射性物質(zhì)發(fā)生泄漏愕秫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評(píng)論 3 327
  • 文/蒙蒙 一焰络、第九天 我趴在偏房一處隱蔽的房頂上張望戴甩。 院中可真熱鬧,春花似錦闪彼、人聲如沸甜孤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)缴川。三九已至,卻和暖如春描馅,著一層夾襖步出監(jiān)牢的瞬間把夸,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工铭污, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留恋日,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,819評(píng)論 2 370
  • 正文 我出身青樓嘹狞,卻偏偏與公主長(zhǎng)得像岂膳,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子磅网,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評(píng)論 2 354