如有引用參考請詳註出處,感謝
XML(eXtensible Markup Language
)可拓展標示語言,又稱為可拓展標記語言,它與 HTML 一樣都是「通用標記語言」(SGML
, Standard Generalized Markup Language
)
其實這種「標記」語言並不算程式語言,因為它無法通過圖靈測試;主要算是 Open stardard 的結構領域,用來做不同裝置之間的通訊
XML 不依賴任何的平台,它是普遍公開的通訊協定
XML 是 W3C 制定的,它的特性如下:
主要目的在「簡單並清晰的 展示(傳遞)數據」,它並不在意數據的索引、排序、查找… 等等的效率,其目的是為了展示,所以相對的也比較耗費空間
好的展示數據是為了給人們觀看
重新定義 SGML 的內部值、參數,只留下常用的功能,像是保留 SGML 的結構化功能!
XML 的標記完全自由定義,不受約束(以下只有第一行為必須,其他標記可以用中文)
對於大小寫敏感
標記成對出現,每一行都需要有結束標記的符號 </>
XML 擁有結構化的特性,開發時常見的 pom.xml
檔案就是 xml 結構… 範例如下
解析 XML 數據的方式有不同種,每種都有其特性、優缺點、解析 XML 的思考方式,像是 SAX
、DOM
、PULL
語法分析器一般來說會有兩種分析想法,然而 想法並沒有對錯(哪個更好),只有在正確的情況下使用對的方式才是最好的
基於「物件」的界面,DOM 就是基於物件去開發
基於「事件」的界面,SAX 就是基於事件去開發
SAX 全名為 Simple API for XML
,它是指一套 API,同時它也是一個開源套件
最早由 Dacid Megginson 使用 Java 語言開發
SAX 的不同之處
它不同於其他大多數 XML 標準,SAX 沒有語言開發商必須遵守的標準 SAX 參考版本,因此 SAX 的不同實現可能採用區別很大的界面
SAX 軟體設計是「事件驅動型」:
簡單來說就是,它會邊依照順序讀取 XML 並 即時的反應給使用 SAX 的程序員
SAX 是透過標準的解析 XML 的界面,即時反饋給使用者,這個解析 XML 的界面是標準界面(Standard Interface
),不會改變
SAX 也不會在記憶體中幫我們建立物件
當掃描到文檔、元素的開始與結束都會透過 XML 的標準驅動 API 反饋給使用者,而 SAX 大多數都有實現 5 種類型的事件
SAX 使用的事件驅動與用戶操作無關,事件只會與 XML 中的元素有關(元素驅動事件)
文檔(Document
)的開始、結束
每次觸發 XML 新的 元素開始、結束(標籤)
MetaData 通常有單獨的事件處理
當處理文檔中的 合法元素 DTD
、Schema
… 時,產生對應的事件
DTD(
Document Type Definition
)是一種用來定義 XML 文件結構和合法元素的規範… 像是CDATA
、ID
、ID
、IDREF
、IDREFS
、NMTOKEN
、NMTOKENS
、ENTITY
、ENTITIES
、NOTATION
、DOCTYPE
以下範例說明著
bookstore 元素是一個包含至少一個 book 元素的元素
book 元素包含 title
、author
和 price
元素
title
、author
和 price
元素都包含字符數據(PCDATA
)
每當產生錯誤事件時,會透過界面通知開發者
org.xml.sax
包 是 JavaSE 使用 SAX 的方式來解析 XML
SAX 使用的常見 XML 解析 界面 如下表
XML 解析界面 | 概述 | 補充 |
---|---|---|
ContentHandler |
文檔本身 相關的事件(像是開始、結束) | 其中也包括元素(Element )監聽 |
EntityResolver |
實體關聯 的事件 | 較少使用 |
DTDHandler |
XML 中的 標準事件 | 然而它定義的事件不夠完整,要完整 DTD 事件的話,可以使用 DeclHandler 界面 |
ErrorHandler |
錯誤事件 | 定義三種級別 1. warning(非 XML 規範)、2. error(XML 定義的錯誤)、3. fatalError(致命錯誤) |
大多數時候都會使用 DefaultHandler
類(有大部分的界面)
SAX 使用的常見 XML 解析 類 如下表
XML 解析類 | 概述 | 補充 |
---|---|---|
XMLReader |
該類可以用 parse 方法,來啟動 XML 語法分析器,它可以接受 1. 文件名、2. URL、3. InputSource |
我們可以以設定 XML 解析監聽器… |
setFeature (Boolean)用來控制語法分析器的工作 |
||
setProperty (物件) 用來控制語法分析器的工作 |
||
XMLReaderFactory |
用來創建 XML 語法分析器物件 | 可創建 1. 系統預設、2. 指定類型(透過設定類路徑) |
InputSource |
控制 SAX 如何讀取文件 | |
SAXException |
SAX 定義的大多數方法都會拋出 SAXException |
目標 XML 如下
使用 SAX API 來解析 XML 數據,並保存在記憶體中
測試使用 SAX API 解析 XML:
DOM(Document Object Model
)提供了一個方便的編程界面,因此可以被視為一種官方的W3C標準
W3C(World Wide Web Consortium
)制定了DOM的標準,並且 DOM 在瀏覽器中被廣泛使用,它允許 JavaScript 通過瀏覽器直接操作 HTML 和 XML 文檔
DOM 會將 XML 完全解析完成後,在記憶體中建立一個 XML 副本(又稱之為物件樹),並且該副本中的所有元素皆以「物件的形式」儲存
DOM & JavaScript 的關係
早期人們會把 DOM 視為是一種讓 JavaScript 在遊覽器間可移植的方法!但其實 DOM 的應用是遠遠超出這個範圍的
DOM 技術使的用戶界面可以「動態變化」,大大增加了交互性
像是 JavaScript 可以透過它動態操作 HTML 的元素的顯示、隱藏
JavaScript 就是利用 DOM 來取得 HTML 文件的操縱入口,並獲得 HTML 對應的物件
根據 W3C DOM 規範,DOM 解析 HTML、XML 這兩類標記語言的界面… DOM 會將整個文件映射為一個由「層次節點」組成的物件
Node 節點
根據 DOM 規範,HTML 文檔中的每一個成份都是節點;有分為「文檔節點」、「元素節點」、「屬性節點」、「文本節點」、「註釋節點」
除了 文檔節點 之外,所有節點都有父節點
DOM API 的分級(共有 3 個分級)
Level 0 DOM / 0 級 DOM 是什麼?
在遊覽器正式規範 DOM 標準之前就存在的規範,它並非有文件的規範,所以是非正規的稱之為 DOM 0,正確一點應該稱其為 BOM(Brower Object Model
)
1 級 DOM:
由 DOM 核心
與 DOM HTML
兩個模塊組層
DOM 核心能映射以「XML 為基礎」的文檔結構為物件,核心 API 會將文件中所有的內容都視為節點,再依照類型區分不同型態
DOM HTML(其實就是拓展核心)則通過添加 HTML 專用的物件與函數對 DOM 核心進行拓展,專門用來操作 HTML
DOM HTML 在瀏覽器開發中較為常見,像是
HTMLHeadElement
元素就提供專屬 HTML 操作的 API
2 級 DOM:
鑑於 1 級 DOM 僅以映射文檔結構到記憶體中(物件樹),2 級 DOM 通過對於源有的 DOM 拓展,針對 DOM 界面增加
DOM 視圖:描述跟蹤一個文檔的各種視圖(使用 CSS 樣式設計文檔前後的差異)
DOM 事件:對於用戶界面事件的反應(像是滑鼠點擊),對這一系列的事件進行標準化
以往尚未標準化時稱之為 基本事件模型(
Basic Event Model
) 或是傳統模型(Traditional model
)
DOM 樣式:基於 CSS 樣式的反應
DOM 遍歷:遍歷、操作文檔物件
支持 XML 的命名空間
XML 的命名空間?
在 XML 中,命名空間(Namespace
)是一種用來「區分元素、屬性名稱的機制」,以「避免名稱衝突」的問題
命名空間在 XML 中通常以一個 URI(Uniform Resource Identifier
)或 URL 來標識
實際上這個 URL 並不要求是一個可訪問的網址
3 級 DOM:
對上一級 DOM 拓展,引入「統一載入」、「保存文件」和「文檔驗證方法」
DOM 核心再次拓展,支持 XML 1.0 的所有設計,像是 XML Infoset
、XPath
、XML Base
… 等等
目標 XML 如下
使用 Javax 提供的 DOM API 來解析 XML 數據,使用 DOM API 的特點在於… 它會一次幫你處理好所有的物件映射關係(以 Node 的方式,儲存在記憶體中)
這樣我們在使用上就不用特別關心 XML 資料流的處理
測試使用 DOM API 解析 XML:
DOM 與 SAX 的令一個不同點在於,它也有提供對應創建(也可以覆蓋)XML 的對應 API;以下我們修改 DOM Parse XML 的範例
首先我們先 Parse XML 得到物件樹,保存在記憶體 List<BookInformation>
內,並返回給 DOM 使用者
再來撰寫一個透過 DOM 提供的 API,來將改變後的數據寫入到新 XML 中…
將使用者設定的新數據,寫入到 DOM 的 Node 節點之中
透過
element
#getElementsByTagName
取得節點,並修改節點數據
使用 DOM 寫 XML 範例
如果是使用 Android 平台開發,除了 SAX、DOM 之外… Android 平台原生還提供了一個內置的 PULL 解析器!同樣可以用來解析 XML 文件
PULL 採用與 SAX 類似的解析方式
它也是採用「事件驅動」的方式解析 XML,當遇到元素時會產生事件並驅動,讓使用者透過界面接收到事件
目標 XML 如下(需要將檔案放置在 assets
目錄下,之後會利用 Android Context 取得目標檔案)
以下使用 Android 系統內提供的 XmlPullParser 來解析 XML 檔案
使用 Android 的機器測試(整合測試)才能測試 Pull 的 Parse
Android XmlPullParser 服務必須運行在 Android Runtime 中
Pull 雖然同 SAX 一樣不會在記憶體中建構物件樹,不過我們仍可以自己透過在記憶體中建立並輸出到目標檔案中(以下方法同樣也可以使用在 SAX)
如果是建立 attribute 的話,那數值會被寫在 tag 中
建立出來的數據就會寫在 tag 中(如下)
測試程式
以下測試運行在 Android App 中(非整合測試)
SAX、DOM 兩者都是對於解析 XML 的方案,不過特點、解決思路都不盡相同,兩者的比較表如下…
\ | SAX | DOM |
---|---|---|
XML 物件建立 | 手動分析、建立 | 自動分析、建立 |
XML 的限制 | 可以讀取不限大小 XML 檔 | 由於會在內存中自動幫我們建立物件樹,所以 XML 大小不能太大 |
XML 讀取 | 以順序方式讀取(不能回頭) | 建立完物件樹後,可隨意讀取 |
XML 修改 | 只能讀取 XML,不能修改! | 可以透過對物件樹的修改,來改動到 XML 檔案 |
技術的特點 | 較為自由(有很多地方可以設定),但相對的也較為麻煩 | 易於操作、開發 |
網路開發