1. 程式人生 > >第三天:XML&反射

第三天:XML&反射

xml

一、XML

1 什麽是XML

XML全稱為Extensible Markup Language,意思是可擴展的標記語言。XML語法上和HTML比較相似,但HTML中的元素是固定的,而XML的標簽是可以由用戶自定義的

2、應用常見

<1>配置文件

技術分享

<2>存放數據

技術分享

3、XML語法

<1>XML文檔聲明

技術分享

①文檔聲明必須為<?xml開頭,以?>結束;

②文檔聲明必須從文檔的0行0列位置開始

③文檔聲明只有三個屬性

a)version:指定XML文檔版本。必須屬性,因為我們不會選擇1.1,只會選擇1.0

b)encoding:指定當前文檔度的編碼。可選屬性,默認值是utf-8

<2>元素element

技術分享

①元素是XML文檔中最重要的組成部分

②普通元素的結構開始標簽、元素體、結束標簽組成。例如:<hello>大家好</hello>

③元素體:元素體可以是元素,也可以是文本,例如:<b><a>你好</a></b>

④空元素:空元素只有開始標簽,而沒有結束標簽,但元素必須自己閉合,例如:<c/>

⑤元素命令:

a)區分大小寫

b)不能使用空格,不能使用冒號;

c)不建議以XML、xml、Xml開頭

⑥格式化良好的XML文檔,必須只有一個根元素

<3>屬性

技術分享

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

②屬性的定義格式:屬性名=屬性值,其中屬性值必須使用單引或雙引

③一個元素可以有0~N個屬性,但一個元素中不能出現同名屬性

④屬性名不能使用空格、冒號等特殊字符,且必須以字母開頭

<4>註釋

XML的註釋與HTML相同,即以“<!--”開始,以“-->”結束。註釋內容會被XML解析器忽略

<5>轉義字符

XML中的轉義字符與HTML一樣

因為很多符號已經被XML文檔結構所使用,所以在元素體或屬性值中想使用這些符號就必須使用轉義字符,例如:“<”、“>”、“&”

技術分享

<6>CDATA區

技術分享

當大量的轉義字符出現在xml文件中時,會使xml文檔的可讀性大幅度降低。這時如果使用CDATA段就會好一些

在CDATA段中出現的“<”、“>”、“&”,都無需使用轉義字符,這可以提高xml文檔的可讀性

在CDATA段中不能包含“]]>”,即CDATA段的結束定界符


4、DTD約束

常見的xml約束:DTD、Schema

<1>什麽是DTD

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

<2>DTD重點

開發中,我們很少自己編寫DTD約束文檔,通常情況我們都是通過框架提供的DTD約束文檔,編寫對應的XML文檔。常見框架使用DTD約束有:struts2、hibernate等

通過提供的DTD“web-app_2_3.dtd”編寫XML

技術分享

<3>案列實現

①步驟1:創建web.xml,並將“web-app_2_3.dtd”拷貝相同目錄下

技術分享

②步驟2:從DTD文檔開始處,拷貝需要的“文檔聲明”

技術分享

③步驟3:完成xml內容編寫

技術分享

技術分享

<4>DTD語法

①文檔申明

內部DTD,在XML文檔內部嵌入DTD,只對當前XML有效

技術分享

外部DTD-本地DTD,DTD文檔在本地系統上,公司內部自己項目使用

技術分享

外部DTD-公共DTD,DTD文檔在網絡上,一般都有框架提供

技術分享

②元素聲明

技術分享

實例

技術分享

③屬性聲明

技術分享

技術分享

實例

技術分享

5、Schema約束

<1>什麽是Schema

Schema是新的XML文檔約束

Schema要比DTD強大很多,是DTD替代者

Schema本身也是XML文檔,但Schema文檔的擴展名為xsd,而不是xml

Schema功能更強大,數據類型更完善

Schema支持名稱空間

<2>Schema重點要求

與DTD一樣,要求可以通過Schema約束文檔編寫xml文檔。常見框架使用Schema的有:Spring等

通過提供“web-app_2_5.xsd”編寫xml文檔

技術分享

技術分享

技術分享

技術分享

案例文檔中同一個“命令空間”分別使用“默認命令空間”和“顯示命令空間”進行引入,所以文檔中<schema>和<xsd:schema>作用一樣

技術分享

<3>案例實現

①步驟1:創建web.xml,並將“web-app_2_5.xsd”拷貝到同級目錄

技術分享

②步驟2:從xsd文檔中拷貝需要的“命令空間”

技術分享

③完成xml內容編寫

技術分享

技術分享

<4>命令空間(語法)

①什麽是命令空間

如果一個XML文檔中使用多個Schema文件,而這些Schema文件定義了相同名稱的元素時就會出現名字沖突,這就像一個java文件中使用了import java.util.*和import java.sql.*時,在使用Date類時,那麽就不明確Date是哪個包下的Date了

名稱空間就是用來處理元素和屬性的名稱沖突問題,與java中的包是同一用途。如果每個元素和屬性都有自己的名稱空間,那麽就不會出現名字沖突問題,就像是每個類都有自己所在的包一樣,那麽類名就不會出現沖突

②約束文檔和XML關系

當W3C提出Schema約束規範時,就提供“官方約束文檔”。我們通過官方文檔,必須“自定義schema約束文檔”,開發中“自定義文檔”由框架編寫者提供,我們提供“自定義文檔”限定,編寫出自己的xml文檔

技術分享

③聲明命令空間

技術分享

實例:web-app_2_5.xsd

技術分享

實例:web.xml

技術分享

④其他介紹

自定義約束:web-app_2_5.xsd

技術分享

xml文檔:web.xml

技術分享

綜合案例:

技術分享

綜合案例目的是:一個“命令空間”必須在schemaLocation中有一個成對描述信息(名稱 路徑)

技術分享

6、dom4j解析

<1>XML解析概述

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

<2>解析方式和解析器

①開發中比較常見的解析方式有三種,如下

Ⅰ、DOM:要求解析器把整個XML文檔裝載到內存,並解析成一個Document對象

a)優點:元素與元素之間保留結構關系,故可以進行增刪改查操作

b)缺點:XML文檔過大,可能出現內存溢出現象

Ⅱ、SAX:是一種速度更快,更有效的方法。它逐行掃描文檔,一邊掃描一邊解析。並以事件驅動的方式 進行具體解析,每執行一行,都將觸發對應的事件

a)優點:處理速度快,可以處理大文件

b)缺點:只能讀,逐行後將釋放資源

Ⅲ、PULL:Android內置的XML解析方式,類似SAX

②解析器:就是根據不同的解析方式提供的具體實現。有的解析器操作過於繁瑣,為了方便開發人員,有提供易於操作的解析開發包

技術分享

③常見的解析開發包:

a)JAXP:sun公司提供支持DOM和SAX開發包

b)JDom:dom4j兄弟

c)jsoup:一種處理HTML特定解析開發包

d)dom4j:比較常用的解析開發包,hibernate底層采用

<3>DOM解析原理及結構模型

XML DOM和HTML DOM類似,XML DOM將整個XML文檔加載到內存,生成一個DOM樹,並獲得一個Document對象,通過Document對象就可以對DOM進行操作

技術分享

技術分享

DOM中的核心概念就是節點,在XML文檔中的元素、屬性、文本等,在DOM中都是節點

技術分享

<4>API使用

如果需要使用dom4j,必須導入jar包

技術分享

dom4j必須使用核心類SaxReader加載xml文檔獲得Document,通過Document對象獲得文檔的根元素,然後就可以操作了

常用API如下:

①SaxReader對象

a)read(...)加載執行xml文檔

②Document對象

a)getRootElement()獲得根元素

③Element對象

a) elements(...) 獲得指定名稱的所有子元素。可以不指定名稱

b) element(...) 獲得指定名稱第一個子元素。可以不指定名稱

c) getName() 獲得當前元素的元素名

d) attributeValue(...) 獲得指定屬性名的屬性值

e) elementText(...) 獲得指定名稱子元素的文本值

f) getText() 獲得當前元素的文本內容

技術分享

技術分享

二、反射

1、什麽是反射

<1>JAVA反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一 個對象,都能夠調用它的任意一個方法和屬性

<2>使用反射,可以在運行時對類Class、構造方法Constructor、普通方法Method、字段Field進行操作

2、Class對象

<1>Class對象,是對class文件(字節碼文件)的描述對象

<2>獲得Class對象

①已知類的完整路徑名(字符串):Class.forName(...)

②已知類型:String.class,確定參數列表

③已知對象:obj.getClass()

<3>常用方法

①使用默認構造方法創建實例:newInstance()

3、Constructor對象

<1>Constructor對象,是構造方法的描述對象

<2>獲得構造方法

①公共的構造方法:Constructor<T> getConstructor(Class<?>...parameterTypes),可變參數用 於確定形式參數列表

②已經聲明的構造方法:

Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes),獲得私有的構造

<3>實例化對象實例

①newInstance(Object...initargs),可變參數用於確定實際參數列表

4、Method對象

<1>Method對象,是普通方法的描述對象

<2>獲得方法:

①獲得公共方法:Method getMethod(String name,Class<?>...parameterTypes)通過方法name獲得 方法,可變參數為方法的形參參數列表

②獲得聲明方法:Method getDeclaredMethod(String name,Class<?>...parameterType)方法操 作;

<3>執行指定方法:

①Object invoke(Object obj,Object...args)執行指定對象obj,指定方法,可變參數為方法的實 際參數列表

5、Field對象

<1>Field對象,是字段的描述對象

<2>獲得方法

①所有字段:Field getField(String name),通過字段名稱

②聲明字段:Field getDeclaredField(String name)

<3>操作

①獲得內容:Object get(Object obj)

②設置內容:void set(Object obj,Object value),確定實例對象

5、案例實現

<1>準備工作

為了模擬服務器程序,且可以同時存在多個類似程序。故提供接口,接口中有3個方法,我們人為約定三個方法的調用順序

技術分享

再為接口編寫實現類

技術分享

技術分享

技術分享

測試,創建實現類實例對象

技術分享

<2>反射執行

測試程序我們直接new HelloServlet,這種編程方式我們稱為硬編碼,即代碼寫死了。為了後期程序的可擴展,開發中通常使用實現類的全限定類名(cn.itcast.e_web.HelloMyServlet),通過反射加載字符串指定的類,並通過反射創建實例

技術分享

技術分享

<3>解析xml

使用反射我們已經可以創建對象的實例,此時我們使用的全限定類名,但程序是仍寫死了,我們將其配置到xml文檔中。

xml文檔內容

技術分享

解析實現

技術分享

技術分享

<4>模擬瀏覽器路徑

上面我們已經解析xml,不過我們獲得內容是固定的。我們希望如果用戶訪問的路徑是/hello,將執行cn.itcast_web.HelloMyServlet程序,如果訪問是/hello2,將執行cn.itcast.e_web.HelloMyServlet2程序。

在執行測試程序前(@Before),解析xml文件,將解析的結果存放在Map中,map中數據的格式為:

路徑=實現類

技術分享

解析xml思路:先解析<servlet>,將結果存放map,name=class,然後再解析<servlet-mapping>

通過name獲得class,再將url=class存放到map,最後將name=class移除

技術分享

技術分享

模擬瀏覽器請求路徑,通過url從map獲得class,並使用反射執行實現類

技術分享

技術分享


本文出自 “鵬哥的博客” 博客,謝絕轉載!

第三天:XML&反射