.NET Framework簡單處理XML數(shù)據(jù)(3)
發(fā)表時間:2024-02-04 來源:明輝站整理相關軟件相關文章人氣:
[摘要]帶驗證的閱讀器 XmlValidatingReader類實現(xiàn)了XmlReader類,它提供了支持多種類型的XML驗證:DTD,XML-Data Reduced(XDR)架構(gòu),以及XSD,DTD和XSD都是W3C官方推薦的。而XDR是Microsoft早期用于處理XML構(gòu)架的一種格式。 你...
帶驗證的閱讀器
XmlValidatingReader類實現(xiàn)了XmlReader類,它提供了支持多種類型的XML驗證:DTD,XML-Data Reduced(XDR)架構(gòu),以及XSD,DTD和XSD都是W3C官方推薦的。而XDR是Microsoft早期用于處理XML構(gòu)架的一種格式。
你可以用XmlVlidatingReader類去驗證XML文檔和XML片斷。XmlValidatingReader類工作在XML閱讀器上面---是一個典型的XMLTextReader類實例。XMLTextReade用于讀取文檔的節(jié)點,但是XmlVlidatingReader依據(jù)需要的驗證類型去驗證每一個XML塊。
XmlVlidatingReader類只實現(xiàn)了非常小的XML閱讀器必備的一個功能子集。該類總是工作在一個已存在的XML閱讀器上面,它監(jiān)視方法和屬性。如果你深入該類的構(gòu)造函數(shù),你會發(fā)現(xiàn)它很明顯的依靠一個已存在的文本閱讀器。帶驗證的XML閱讀器不能直接的從一個文件或一個URL序列化。該類的構(gòu)造函數(shù)列表如下:
public XmlValidatingReader(XmlReader);
public XmlValidatingReader(Stream, XmlNodeType, XmlParserContext);
public XmlValidatingReader(string, XmlNodeType, XmlParserContext);
帶驗證的XML閱讀器能分析任何的XML片斷,XML片斷通過一個string或者一個stream提供,也可以分析任何閱讀器提供的XML文檔。
XmlVlidatingReader類中有重大改變的方法非常少(相對其它reader類來說),另外對 Read,它有Skip和ReadTypedValue方法。Skip方法跳過當前節(jié)點所有的子節(jié)點(你不能跳過不良格式的XML文本,它是相當有用的算法),Skip方法也驗證被跳過的內(nèi)容。ReadTypedValue方法返回指定 XML 架構(gòu) (XSD) 類型對應的CLR類型。如果該方法找到了XSD類型對應的CLR類型,則返回CLR的類型名。如果找不到,則把該節(jié)點的值作為一個字符串值返回。
帶驗證的XML閱讀器正如其名,它是一個基于節(jié)點的閱讀器,它驗證當前節(jié)點的結(jié)構(gòu)是否符合當前的schema。驗證是增量式的;它沒有方法返回表示文檔是否有效的布爾值。通常你都是用Read方法去讀輸入的XML文檔。實際上,你也可以用帶驗證的閱讀器去讀XML文檔。在每一步中,當前被訪問的節(jié)點的結(jié)構(gòu)是否與指定的schema符合,如果不符合,拋出一個異常。圖四是一個控制臺應用程序,它有一個要輸入文件名的命令行,最后輸出驗證結(jié)果。
Figure 4 Console App
using System;
using System.Xml;
using System.Xml.Schema;
class MyXmlValidApp
{
public MyXmlValidApp(String fileName)
{
try {
Validate(fileName);
}
catch (Exception e) {
Console.WriteLine("Error:\t{0}", e.Message);
Console.WriteLine("Exception raised: {0}",
e.GetType().ToString());
}
}
private void Validate(String fileName)
{
XmlTextReader xtr = new XmlTextReader(fileName);
XmlValidatingReader vreader = new XmlValidatingReader(xtr);
vreader.ValidationType = ValidationType.Auto;
vreader.ValidationEventHandler += new
ValidationEventHandler(this.ValidationEventHandle);
vreader.Read();
vreader.MoveToContent();
while (vreader.Read()) {}
xtr.Close();
[page_break]vreader.Close();
}
public void ValidationEventHandle(Object sender,
ValidationEventArgs args)
{
Console.Write("Validation error: " + args.Message + "\r\n");
}
public static void Main(String[] args)
{
MyXmlValidApp o = new MyXmlValidApp(args[0]);
return;
}
}
ValidationType屬性設置驗證的類型,它可以是:DTD, XSD, XDR或者none。如果沒有指定驗證的類型(用ValidationType.Auto選項),閱讀器將自動的根據(jù)文檔用最適合的驗證類型。在驗證過程中出現(xiàn)任何錯誤,都會觸發(fā)ValidationEventHandler事件。如果未提供事件ValidationEventHandler事件處理程序,則拋出一個XML異常。定義ValidationEventHandler事件處理程序是用于捕捉任何在XML源文件中存在錯誤而引發(fā)XML異常的一種方法。要注意的是閱讀器的原理是檢查一個文檔是否是格式良好的,以及檢查文檔是否與架構(gòu)吻合。如果帶驗證的閱讀器發(fā)現(xiàn)一個有嚴重的格式錯誤的XML文檔,只會觸發(fā)XmlException異常,它不會觸發(fā)其它的事件。
驗證發(fā)生在用戶用Read方法向前移動指針時,一旦節(jié)點被分析和讀取,它獲得傳送過來的處理驗證的內(nèi)部的對象。驗證操作是基于節(jié)點類型及被要求的驗證類型。它確認節(jié)點所有的屬性和節(jié)點包含的子節(jié)點是否符合驗證條件。
驗證對象在內(nèi)部調(diào)用兩個不同風格的對象:DTD分析器和架構(gòu)生成器(schema builder)。DTD分析器處理當前節(jié)點的內(nèi)容和不符合DTD的子樹。架構(gòu)生成器根據(jù)XDR或者XSD架構(gòu)對當前的節(jié)點構(gòu)建一個SOM(schema object model)。架構(gòu)生成器類實際上是所有指定為XDR和XSD架構(gòu)生成器的基類。為什么呢,雖然XDR和XSD架構(gòu)的許多相同的方法被加工處理過,但是它們在執(zhí)行時的性能沒有區(qū)別。
如果節(jié)點有子節(jié)點,用另一個臨時的閱讀器收集子節(jié)點信息,因此節(jié)點的架構(gòu)信息能被完全地驗證。你可以看圖五:
注意,盡管XmlValidatingReader類的構(gòu)造函數(shù)可以接受一個XmlReader類作為其閱讀器,但是該閱讀器只能是XmlTextReader類的一個實例或者是它的一個派生類的實例。這意味著你不能用其它從XmlReader派生的類(例如一個自定義的XML閱讀器)。在XmlValidatingReader類的內(nèi)部,它假設閱讀器是一個子XmlTextReader對象及把傳入的閱讀器顯式的轉(zhuǎn)換成XmlTextReader類。如果你用XmlNodeReader或者自定義的閱讀器器,程序在編譯時會出錯,運行時拋出一個異常。
節(jié)點閱讀器
XML閱讀器提供一種增量式的方法(一個一個節(jié)點的讀)來處理文檔的內(nèi)容。到目前為止,我們假設源文件是一個基于硬盤的流或者是一個字符串流,然而,我們不能保證在實際中會提供一個源文件的XMLDOM對象給我們。在這種情況下,我們需要一個帶有特別的讀方法的特別的類。對這種情況,.NET Framework提供了XmlNodeReader類。
就像XmlTextReader訪問指定XML流中所有節(jié)點一樣,XmlNodeReader類訪問XMLDOM子樹的所有節(jié)點。XMLDOM類(在.NET Framework中的XmlDocument類)支持基于Xpath的方法,例如SelectNodes方法和SelectSingleNode方法。這些方法的作用是把匹配的節(jié)點放在內(nèi)存中。如果你需要處理子樹中的所有節(jié)點,節(jié)點閱讀器比用增量式方法處理節(jié)點的閱讀器具有更高的效率:
// xmldomNode is the XML DOM node
XmlNodeReader nodeReader = new XmlNodeReader(xmldomNode);
while (nodeReader.Read())
{
// Do something here
}
當你要在配置文件(例如web.cofig文件)中引用自定義的數(shù)據(jù)時,先把這些數(shù)據(jù)填充到XMLDOM樹中,然后用XmlNodeReader類與XMLDOM類結(jié)合處理這些數(shù)據(jù)。這也是高效的。