在前兩篇文章中我們討論了XML文件的讀取和寫入,但都是基於流模型的解決方案,今天我們就來談談在C#中如何實現DOM,DOM確實有它的不足,但在編程工作中它還是不可或缺的技術。下面我們來簡單了解一下DOM的相關知識。
DOM的全稱是Document Object Model(文檔對象模型),它是來自W3C的官方標准,它允許按照W3C標准W3C DOM Level1和W3C DOM Level2的規范所定義的規則,通過編程來讀取,操縱和修改XML文檔。DOM的工作方式是:首先將XML文檔一次性的裝入內存,然後根據文檔中定義的元素和屬性在內存中創建一個“樹型結構”也就是一個文檔對象模型,這裡的含義其實是把文檔對象化,文檔中每個節點對應著模型中一個對象,而我們都知道對象提供編程接口,所以在Application中我們正是使用這組對象來訪問XML文檔進而操作XML文檔,下圖闡述了Application和DOM交互的過程:
DOM既然是在內存中創建樹型結構視圖進而提供編程接口,那我們就以下面這個XML片段來說明DOM是如何創建樹型結構的:
<parent>
<child id=”123”>text here</child>
</parent>
如果用DOM加載以上文檔,它將在內存中創建的樹型結構如下圖:
DOM的關鍵在於它允許直接更新內存中的樹型結構,而不必重定向到其他輸出,因此,添加、更新或刪除結構中信息的操作效率更高。而作為程序員的我們重要的是要了解DOM所提供的編程接口以實現對XML文檔進行操作,事實上,.NET Framework定義了一組類用於反映DOM的體系結構,下面來看一下.NET DOM的繼承結構:
在上圖中所有弧角矩形中所包含的類描述了所有可能在XML文檔中出現的節點類型,而操作XML文檔不外乎是操作其中的節點,這些類又都是從XmlNode類派生而來,所以我們今天的主題是討論XmlNode類和它的子類XmlDocument,下面對這些類做簡單的介紹:
XmlNode類:
該類是DOM中所有其他節點的抽象基類,它定義所有在更低級的類中繼承或重寫的成員。它表示XML文檔中的單一節點,它提供了用於導航DOM樹型結構的基本方法和屬性,使用XmlNodeType枚舉器可以枚舉其下的所有節點類型。以下介紹該類的部分屬性和方法:
屬性:
[C#]
public virtual bool HasChildNodes {get;} 獲取一個值,該值指示當前節點是否有任何子節點
public virtual XmlNodeList ChildNodes {get;} 獲取當前節點的所有子節點
public virtual XmlNode FirstChild {get;} 獲取當前節點的第一個子級
public virtual XmlNode LastChild {get;} 獲取當前節點的最後一個子級
public virtual XmlNode ParentNode {get;} 獲取當前節點的父級
public virtual XmlNode NextSibling {get;} 獲取當前節點的下一個兄弟節點
public virtual XmlNode PreviousSibling {get;} 獲取當前節點的上一個兄弟節點
public virtual string InnerText {get; set;} 獲取或設置當前節點及其所有子節點的文本內容的串聯值
public virtual string InnerXml {get; set;} 獲取或設置僅代表當前節點的子節點的標記
public virtual string OuterXml {get;} 獲取表示當前節點及其所有子節點的標記
方法:
public XmlNodeList SelectNodes(string); 選擇文檔中匹配 XPath 表達式的節點列表
public XmlNode SelectSingleNode(string); 選擇文檔中匹配 XPath 表達式的第一個 XmlNode
public virtual XmlNode AppendChild(XmlNode newChild) 將指定的節點添加到該節點的子節點列表的末尾
public virtual XmlNode PrependChild(XmlNode newChild) 將指定的節點添加到該節點的子節點列表的開頭
public virtual XmlNode RemoveChild(XmlNode oldChild) 移除指定的子節點
public virtual XmlNode ReplaceChild(XmlNode newChild,XmlNode oldChild) 用 newChild 節點替換子節點 oldChild
XmlNodeList類:
該類表示XmlNode的有序集合,它有以下常用成員:
Count——以整數形式返回XmlNodeList中的節點數
ItemOf——搜索在指定索引處的節點
GetEnumerator()——提供迭代遍歷節點列表的foreach樣式
Item()——返回參數指定的索引處的節點
XmlDocument類:
XmlDocument類是XML文檔的.NET表示形式,它代表了內存中樹型結構的文檔節點(所有的節點都在文檔節點下),XmlDocument類包含所有的CreateXXX()方法,這些方法允許創建所有派生自XmlNode的類型的節點,通常將該類與XmlNode類一起使用以完成對文檔的操作,該類有一個Load()方法用於加載XML文檔,該方法的一個重載版本允許從XmlTextReader加載文檔,這給我們帶來的好處是在操作較大的文檔時我們可以先使用XmlTextReader過濾不相關的文檔部分,這樣即解決了DOM所帶來的資源損耗問題又可以保留DOM對文檔操控的便利性,該類的Save()方法用於保存文檔。
接下來用一個簡單的例子來說明在C#中如何實現DOM,照舊看代碼前先看下運行效果圖:
LoadXML按紐用於加載XML文檔,LoadXMLReader按紐使用XmlTextReader加載文檔,SaveXML按紐保存文檔,SaveXMLWriter按紐將文檔保存到XmlTextWriter中,Add Product按紐添加節點,Replace Product按紐替換節點,Change Order按紐修改文檔,Remove Product Info按紐移除節點。
DomOperation類封裝了所有按紐功能的實現