在.NET Framework中輕鬆處理XML資料(二)

來源:互聯網
上載者:User
xml|資料

分析屬性值

大部分情況下,屬性值都是一個簡單的文本字串。然而,這並不意味著實際應用中的屬性值都是字元型的。有時候,屬性值是由許多種類型的資料群組合而成的,例如Date或Boolean,這時,你就要用XmlConvert或System.Convevt類的方法把這些類型轉換成原來的類型。XmlConvert和System.Convevt類都能實現資料類型的轉換,但是XmlConvert類依據XSD中指定的資料類型進行轉換,而不管它現在是什麼類型。

假設你有以下的XML資料片斷:

讓我們先確認,birthdaay屬性值是February 8, 2001,如果你用System.Convert類把該字串轉換成.NET Framework中的DateTime類型,這樣,我們就可以把它當成date類型使用了。相比下,如果你用XmlConvert類來轉換字串,你將看到一個分析錯誤,因為XmlConvert類不能正確解釋這個字串中的日期。因為在XML中,日期型資料的格式必須是YYYY-MM-DD形式的。XmlConvert類擔任CLR類型與XSD類型之間的相互轉換工作。當轉換工作發生時,轉換結果是局部的。

在某些解決方案中,屬性值是由純文字和實體共同組成的。在所有的閱讀器類中,只有XmlValidatingReader類能處理實體。XmlTextReader雖然不能處理實體,但它們同時出現在屬性值中的時候,它只能把文本值取出來。出現這種情況,你必須用ReadAttributeValue方法替代簡單的讀方法來分析屬性值的內容。

ReadAttributeValue方法分析屬性值,然後把各個組成的要素分隔開(如把純文字和實體分開)。你可以用ReadAttributeValue方法的傳回值作為迴圈條件,遍曆整個屬性值中的要素。既然XmlTextReader類不能處理實體,那麼你可以自己寫一個用於處理實體的類。下面的代碼片斷示範了怎麼調用一個自訂的處理類:

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, 從而結束迴圈。屬性值的最終結果就是全域變數buffer的值了。

處理XML文本(Text)

當我們在處理XML標籤文本時,如果不能正確的處理,它的錯誤原因能很快地確定。例如一個字元轉換錯誤,它必然是傳輸了非XML文本到一個XML資料流中。不是所有在給定的平台中有效字元都是有效XML字元。只有在XML規範(www.w3.org/TR/2000/REC-xml-20001006.html)中規定的有效字元才能安全的用作元素和屬性名稱。

XmlConvert類提供了把非XML標準的命名轉換成標準的XML命名的功能。當標籤名中包含有無效的XML字元時,EncodeName 和 DecodeName方法能把它們調整成符合Schema的XML命名。包括SQL Server? 和Microsoft Office,這些應用程式允許及支援Unicode文檔,然而,這些文檔中的字元有些也不是有效XML命名。典型的情況是在你處理資料庫中包含空格的列名時。雖然SQL Server允許長列名,但這對XML流來說可能就不是有效命名。空格會被十六進位代碼Invoice_0x0020_Details替代。下面的代碼示範了怎麼樣在程式中獲得該字串:

XmlConvert.EncodeName("Invoice Details");

與此相反的方法是DecodeName。該方法把XML文本轉換成其原始的格式。要注意的是它只能轉換完整的十六進位代碼,只有_0x0020_才被當成一個空格,而_0x20_就不是了:

XmlConvert.DecodeName("Invoice_0x0020_Details");

在XML文檔中的空格即重要也不重要。說它重要,是當它出現在元素的內容中或者它在備註陳述式中時,它能表示實際意義。例如下面的情況:

<MyNode xml:space="preserve">

<!-- any space here must be preserved -->

???

</MyNode>

在xml中,空格不只是代表空格(空白),也代表斷行符號、換行和縮排。

通過XmlTextReader類的WhiteSpaceHandling屬性你可以處理空格。這個屬性接受及返回一個WhiteSpaceHandling枚舉值(該枚舉類有三種可選值)。預設值是All,它表示有意義和無意義的空格都會作為節點返回---- 分別為SignificantWhitespace和Whitespace節點。 另一個枚舉值是None,它表示對任何空格都不作為節點返回。最後,就是Signficant枚舉值,它表示忽略沒有意義的空格,而只返回節點類型為SignficantWhitespace的節點。注意WhiteSpaceHandling屬性是少數閱讀器屬性中的一個。它能被改變在任何時候和給Read操作帶來影響。而Normalization及 XmlResolver屬性是“Sensitive”的。

String和Fragment

程式員把在MSXML的程式剪下下來,會發現在COM和.NET Framework XML API 之間的差別很大。.NET Framework類本身沒有提供方法去分析儲存在字串中XML資料。不像MSXML分析器對象,XmlTestReader類沒有提供任何一種LoadXML方法從一個格式良好的字元中建立閱讀器。沒有提供類似LoadXML的方法因為你可以用特殊的text reader---StringReader類來獲得同樣的功能。

XmlTextReader其中一個建構函式接受一個TextReader派生對象和一個XML reader作參數(該閱讀器以text reader的內容為基礎建立)。一個text reader類是一個流,這個流是輸入的字元經最佳化產生的。StringReader類繼承TextReader類,並用一個記憶體中字串作為其輸入資料流。下面的代碼片斷示範了怎樣初始化一個XML reader,用一個格式良好的XML 字串作為其輸入:

string xmlText = "...";

StringReader strReader = new StringReader(xmlText);

XmlTextReader reader = new XmlTextReader(strReader);

另外,用StringWriter類代替TextWrite類,你可以從記憶體字元中建立一個XML文檔。

一個指定類型的XML字串是一個XML片斷(fragment). XML片斷由XML文本構成,但沒有根節點的XML文檔不是格式良好的XML文檔,所以不能被應用。一個XML片斷是原始的文檔的一部分,所以它可能缺少根節點。例如,下面的XML文本是一個有效XML 片斷,但不是一個有效XML文檔,因為它沒有根節點:

Dino

Esposito

.NET Framework XML API允許程式員把XML片斷與一個分析器內容結合使用,分析器內容由類似encoding字元集,DTD文檔,命名空間,語言和空格處理常式構成:

public XmlTextReader(

string xmlFragment,

XmlNodeType fragType,

XmlParserContext context

);

xmlFragment參數包括了XML字串分析。FragType參數表示fragment的類型,它給出了fragment根節點的類型。只有element,attibute和document類型的節點才能作為fragment的根節點,分析器的內容才能被XmlParserContext類解釋。

    作者:chyich(譯)/ASPCool



相關文章

Alibaba Cloud 10 Year Anniversary

With You, We are Shaping a Digital World, 2009-2019

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。