在.NET Framework中簡(jiǎn)單處理XML數(shù)據(jù)(4-1)
發(fā)表時(shí)間:2024-02-06 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]XmlTextWriter類(lèi) 用在本節(jié)中的方法創(chuàng)建XML文檔顯然并不困難。多年以來(lái),開(kāi)發(fā)者都是通過(guò)在緩存在連接一些字符串,連接好以后再把緩存中字符串輸出到文件的方式來(lái)創(chuàng)建XML文檔。但是以這種方式創(chuàng)建XML文檔的方法只有在你保證字符串中不存在任何細(xì)小的錯(cuò)誤的時(shí)候才有效。.NET Frame...
XmlTextWriter類(lèi) 用在本節(jié)中的方法創(chuàng)建XML文檔顯然并不困難。多年以來(lái),開(kāi)發(fā)者都是通過(guò)在緩存在連接一些字符串,連接好以后再把緩存中字符串輸出到文件的方式來(lái)創(chuàng)建XML文檔。但是以這種方式創(chuàng)建XML文檔的方法只有在你保證字符串中不存在任何細(xì)小的錯(cuò)誤的時(shí)候才有效。.NET Framework通過(guò)用XMLwriter提供了更好的創(chuàng)建XML文檔的方法。
XML Writer類(lèi)以只前(forward-only)的方式輸出XML數(shù)據(jù)到流或者文件中。更重要的是,XML Writer在設(shè)計(jì)時(shí)就保證所有的XML數(shù)據(jù)都符合W3C XML 1.0推薦規(guī)范,你甚至不用擔(dān)心忘記寫(xiě)閉標(biāo)簽,因?yàn)閄ML Writer會(huì)幫你寫(xiě)。XmlWriter是所有 XML writer的抽象基類(lèi)。.NET Framework只提供唯一的一個(gè)writer 類(lèi)----XmlTextWriter類(lèi)。
我們先來(lái)看看XML writers和舊的writers的不同點(diǎn),下面的代碼保存了一個(gè)string型的數(shù)組:
StringBuilder sb = new StringBuilder("");
sb.Append("
");
foreach(string s in theArray) {
sb.Append("
sb.Append(s);
sb.Append("\"/>");
}
sb.Append("");
代碼通過(guò)循環(huán)取出數(shù)據(jù)中的元素,寫(xiě)好標(biāo)簽文本并把它們累加到一個(gè)string中。代碼保證輸出的內(nèi)容是格式良好的并且注意了新行的縮進(jìn),及支持命名空間。當(dāng)創(chuàng)建的文檔結(jié)構(gòu)比較簡(jiǎn)單時(shí),這種方法可能不會(huì)有錯(cuò)誤。然而,當(dāng)你要支持處理指令,命名空間,縮進(jìn),格式化以及實(shí)體的時(shí)候,代碼的數(shù)量就成指數(shù)級(jí)增長(zhǎng),出錯(cuò)的可能性也隨之增長(zhǎng)。
XML writer寫(xiě)方法功能對(duì)應(yīng)每個(gè)可能的XML節(jié)點(diǎn)類(lèi)型,它使創(chuàng)建xml文檔的過(guò)程更符合邏輯、更少的信賴于繁瑣的標(biāo)記語(yǔ)言。圖六演示了怎么樣用XmlTextWriter類(lèi)的方法來(lái)連接一個(gè)string數(shù)據(jù)。代碼很簡(jiǎn)潔,用XML writer的代碼更容易讀、結(jié)構(gòu)更好。
Figure 6 Serializing a String Array
void CreateXmlFileUsingWriters(String[] theArray, string filename)
{
// Open the XML writer (用默認(rèn)的字符集)
XmlTextWriter xmlw = new XmlTextWriter(filename, null);
xmlw.Formatting = Formatting.Indented;
xmlw.WriteStartDocument();
xmlw.WriteStartElement("array");
foreach(string s in theArray)
{
xmlw.WriteStartElement("element");
xmlw.WriteAttributeString("value", s);
xmlw.WriteEndElement();
}
xmlw.WriteEndDocument();
// Close the writer
xmlw.Close();
}
然而XML writer并不是魔術(shù)師----它不能修復(fù)輸入的錯(cuò)誤。XML writer不會(huì)檢查元素名和屬性名是否有效,也不保證被用的任何的Unicode字符集適合當(dāng)前架構(gòu)的編碼集。如上所述,為了避免輸出錯(cuò)誤,必須要杜絕非XML字符。但是writer沒(méi)有提供這種方法。
另外,當(dāng)創(chuàng)建一個(gè)屬性節(jié)點(diǎn)時(shí),Writer不會(huì)檢驗(yàn)屬性節(jié)點(diǎn)的名稱(chēng)是否與已存在的元素節(jié)點(diǎn)的名稱(chēng)相同。最后,XmlWriter類(lèi)不是一個(gè)帶驗(yàn)證的Writer類(lèi),也不保證輸出是否符合schema或者DTD。在.NET Framework中帶驗(yàn)證的writer類(lèi)目前來(lái)說(shuō)還沒(méi)有提供。但是在我寫(xiě)的《Applied XML Programming for Microsoft .NET (Microsoft Press®, 2002)》書(shū)中,我自己寫(xiě)了一個(gè)帶驗(yàn)證的Writer組件。你可以到下面的網(wǎng)址去下載源碼:http://www.microsoft.com/MSPress/books/6235.asp.
圖七列出了XML writer的一些狀態(tài)值(state)。這些值都源于WriteState枚舉類(lèi)。當(dāng)你創(chuàng)建一個(gè)Writer,它的初始狀態(tài)為Start,表示你將要配置該對(duì)象,實(shí)際上writer沒(méi)有開(kāi)始。下一個(gè)狀態(tài)是Prolog,該狀態(tài)是當(dāng)你調(diào)用WriteStartDocument方法開(kāi)始工作的時(shí)候設(shè)置的。然后,狀態(tài)的轉(zhuǎn)換就取決于你的寫(xiě)的文檔及文檔的內(nèi)容了。Prolog狀態(tài)一直保留到當(dāng)你增加一個(gè)非元素節(jié)點(diǎn)時(shí),例如注釋元素,處理指令及文檔類(lèi)型。當(dāng)?shù)谝粋(gè)節(jié)點(diǎn)也就是根節(jié)點(diǎn)寫(xiě)完后,狀態(tài)就變?yōu)镋lement。當(dāng)你調(diào)用WriterStartAtribute方法時(shí)狀態(tài)轉(zhuǎn)換為Attribute,而不是當(dāng)你調(diào)用WriteAtributeString方法寫(xiě)屬性時(shí)轉(zhuǎn)換為該狀態(tài)。如果那樣的話,狀態(tài)應(yīng)該是Element。當(dāng)你寫(xiě)一個(gè)閉標(biāo)簽(>)時(shí),狀態(tài)會(huì)轉(zhuǎn)換成Content。當(dāng)你寫(xiě)完文檔后,調(diào)用WriteEndDocument方法,狀態(tài)就會(huì)返回為Start,直到你開(kāi)始寫(xiě)另一個(gè)文檔或者把Writer關(guān)掉。