明輝手游網(wǎng)中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

.NET Framework簡單處理XML數(shù)據(jù)(二)

[摘要]分析屬性值 大部分情況下,屬性值都是一個簡單的文本字符串。然而,這并不意味著實際應(yīng)用中的屬性值都是字符型的。有時候,屬性值是由許多種類型的數(shù)據(jù)組合而成的,例如Date或Boolean,這時,你就要用XmlConvert或System.Convevt類的方法把這些類型轉(zhuǎn)換成原來的類型。XmlCo...
分析屬性值
大部分情況下,屬性值都是一個簡單的文本字符串。然而,這并不意味著實際應(yīng)用中的屬性值都是字符型的。有時候,屬性值是由許多種類型的數(shù)據(jù)組合而成的,例如Date或Boolean,這時,你就要用XmlConvert或System.Convevt類的方法把這些類型轉(zhuǎn)換成原來的類型。XmlConvert和System.Convevt類都能實現(xiàn)數(shù)據(jù)類型的轉(zhuǎn)換,但是XmlConvert類依據(jù)XSD中指定的數(shù)據(jù)類型進行轉(zhuǎn)換,而不管它現(xiàn)在是什么類型。
假設(shè)你有以下的XML數(shù)據(jù)片斷:

讓我們先確認,birthdaay屬性值是February 8, 2001,如果你用System.Convert類把該字符串轉(zhuǎn)換成.NET Framework中的DateTime類型,這樣,我們就可以把它當成date類型使用了。相比下,如果你用XmlConvert類來轉(zhuǎn)換字符串,你將看到一個分析錯誤,因為XmlConvert類不能正確解釋這個字符串中的日期。因為在XML中,日期型數(shù)據(jù)的格式必須是YYYY-MM-DD形式的。XmlConvert類擔任CLR類型與XSD類型之間的相互轉(zhuǎn)換工作。當轉(zhuǎn)換工作發(fā)生時,轉(zhuǎn)換結(jié)果是局部的。
在某些解決方案中,屬性值是由純文本和實體共同組成的。在所有的閱讀器類中,只有XmlValidatingReader類能處理實體。XmlTextReader雖然不能處理實體,但它們同時出現(xiàn)在屬性值中的時候,它只能把文本值取出來。出現(xiàn)這種情況,你必須用ReadAttributeValue方法替代簡單的讀方法來分析屬性值的內(nèi)容。
ReadAttributeValue方法分析屬性值,然后把各個組成的要素分隔開(如把純文本和實體分開)。你可以用ReadAttributeValue方法的返回值作為循環(huán)條件,遍歷整個屬性值中的要素。既然XmlTextReader類不能處理實體,那么你可以自己寫一個用于處理實體的類。下面的代碼片斷演示了怎么調(diào)用一個自定義的處理類:
while(reader.ReadAttributeValue())
{
if (reader.NodeType == XmlNodeType.EntityReference)
// Resolve the "reader.Name" reference and add
// the result to a buffer
buf += YourResolverCode(reader.Name);
else
// Just append the value to the buffer
buf += reader.Value;
}
當屬性值全部被分析后,ReadAtributeValue方法返回False, 從而結(jié)束循環(huán)。屬性值的最終結(jié)果就是全局變量buffer的值了。
處理XML文本(Text)
當我們在處理XML標簽文本時,如果不能正確的處理,它的錯誤原因能很快地確定。例如一個字符轉(zhuǎn)換錯誤,它必然是傳輸了非XML文本到一個XML數(shù)據(jù)流中。不是所有在給定的平臺中有效的字符都是有效的XML字符。只有在XML規(guī)范(www.w3.org/TR/2000/REC-xml-20001006.html)中規(guī)定的有效的字符才能安全的用作元素和屬性名。
XmlConvert類提供了把非XML標準的命名轉(zhuǎn)換成標準的XML命名的功能。當標簽名中包含有無效的XML字符時,EncodeName 和 DecodeName方法能把它們調(diào)整成符合Schema的XML命名。包括SQL Server? 和Microsoft Office,這些應(yīng)用程序允許及支持Unicode文檔,然而,這些文檔中的字符有些也不是有效的XML命名。典型的情況是在你處理數(shù)據(jù)庫中包含空格的列名時。雖然SQL Server允許長列名,但這對XML流來說可能就不是有效的命名?崭駮皇M制代碼Invoice_0x0020_Details替代。下面的代碼演示了怎么樣在程序中獲得該字符串:
XmlConvert.EncodeName("Invoice Details");
與此相反的方法是DecodeName。該方法把XML文本轉(zhuǎn)換成其原始的格式。要注意的是它只能轉(zhuǎn)換完整的十六進制代碼,只有_0x0020_才被當成一個空格,而_0x20_就不是了:
XmlConvert.DecodeName("Invoice_0x0020_Details");
在XML文檔中的空格即重要也不重要。說它重要,是當它出現(xiàn)在元素的內(nèi)容中或者它在注釋語句中時,它能表示實際意義。例如下面的情況:
[page_break]<MyNode xml:space="preserve">
<!-- any space here must be preserved -->
???
</MyNode>
在xml中,空格不只是代表空格(空白),也代表回車、換行和縮進。
通過XmlTextReader類的WhiteSpaceHandling屬性你可以處理空格。這個屬性接受及返回一個WhiteSpaceHandling枚舉值(該枚舉類有三種可選值)。默認值是All,它表示有意義和無意義的空格都會作為節(jié)點返回---- 分別為SignificantWhitespace和Whitespace節(jié)點。 另一個枚舉值是None,它表示對任何空格都不作為節(jié)點返回。最后,就是Signficant枚舉值,它表示忽略沒有意義的空格,而只返回節(jié)點類型為SignficantWhitespace的節(jié)點。注意WhiteSpaceHandling屬性是少數(shù)閱讀器屬性中的一個。它能被改變在任何時候和給Read操作帶來影響。而Normalization及 XmlResolver屬性是“Sensitive”的。
String和Fragment
程序員把在MSXML的程序剪切下來,會發(fā)現(xiàn)在COM和.NET Framework XML API 之間的差別很大。.NET Framework類本身沒有提供方法去分析存儲在字符串中XML數(shù)據(jù)。不像MSXML分析器對象,XmlTestReader類沒有提供任何一種LoadXML方法從一個格式良好的字符中創(chuàng)建閱讀器。沒有提供類似LoadXML的方法因為你可以用特殊的text reader---StringReader類來獲得同樣的功能。
XmlTextReader其中一個構(gòu)造函數(shù)接受一個TextReader派生對象和一個XML reader作參數(shù)(該閱讀器以text reader的內(nèi)容為基礎(chǔ)創(chuàng)建)。一個text reader類是一個流,這個流是輸入的字符經(jīng)優(yōu)化生成的。StringReader類繼承TextReader類,并用一個內(nèi)存中字符串作為其輸入流。下面的代碼片斷演示了怎樣初始化一個XML reader,用一個格式良好的XML 字符串作為其輸入:
string xmlText = "...";
StringReader strReader = new StringReader(xmlText);
XmlTextReader reader = new XmlTextReader(strReader);

另外,用StringWriter類代替TextWrite類,你可以從內(nèi)存字符中創(chuàng)建一個XML文檔。
一個指定類型的XML字符串是一個XML片斷(fragment). XML片斷由XML文本構(gòu)成,但沒有根節(jié)點的XML文檔不是格式良好的XML文檔,所以不能被應(yīng)用。一個XML片斷是原始的文檔的一部分,所以它可能缺少根節(jié)點。例如,下面的XML文本是一個有效的XML 片斷,但不是一個有效的XML文檔,因為它沒有根節(jié)點:
Dino
Esposito
.NET Framework XML API允許程序員把XML片斷與一個分析器內(nèi)容結(jié)合使用,分析器內(nèi)容由類似encoding字符集,DTD文檔,命名空間,語言和空格處理程序構(gòu)成:
public XmlTextReader(
string xmlFragment,
XmlNodeType fragType,
XmlParserContext context
);
xmlFragment參數(shù)包括了XML字符串分析。FragType參數(shù)表示fragment的類型,它給出了fragment根節(jié)點的類型。只有element,attibute和document類型的節(jié)點才能作為fragment的根節(jié)點,分析器的內(nèi)容才能被XmlParserContext類解釋。