程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> ASP.NET >> 關於ASP.NET >> LINQ學習筆記:string類型的Value屬性

LINQ學習筆記:string類型的Value屬性

編輯:關於ASP.NET

與Value打交道

XElement與XAttribute的都有一個string類型的Value屬性. 如果一個元素包含有一個單一的XText子節點, 那麼XElement的Value屬性就相當於訪問此節點內容的快捷方式. 對於XAttribute, Value屬性就是指attribute的值.

盡管存儲體不一樣, X-DOM還是提供了一致的操作方式用於元素和attribute的值.

設置Values

有兩中方式用於分配一個值: 調用SetValue或者賦值給Value屬性. 相比之下SetValue更加靈活一點, 因為它不僅僅接受string類型, 也可以接受其他的簡單類型:

   1: var e = new XElement ("date", DateTime.Now);
   2: e.SetValue (DateTime.Now.AddDays(1));
   3: Console.Write (e.Value);

我們可以簡單的設置值到元素的Value屬性, 但這意味著你需要手動將DateTime轉換成string類型. 這將會更加復雜–因為它需要使用XmlConvert來轉換成為一個XML兼容的結果.

獲取Values

為了將一個Value值轉換成為其基礎類型, 我們可以簡單轉換XElement或者XAttribute到我們期望的類型. 這聽起來似乎是不能工作的, 但實際上是它完全沒有任何問題. 例如:

   1: XElement e = new XElement ("now", DateTime.Now);
   2: DateTime dt = (DateTime) e;
   3:
   4: XAttribute a = new XAttribute ("resolution", 1.234);
   5: double res = (double) a;

一個元素或者attribute並不會天然的存儲DateTime或者數字–他們總是將其保存為文本, 然後轉換為真正需要的. 它也沒有記住其原始類型, 因為你必須要將其轉換為正確的類型以避免出現運行時錯誤.要讓你的代碼更加健壯, 可以使用try / catch塊, 捕獲一個FormatException.

XElement與XAttribute的顯式轉換可以將其轉換為以下的類型:

  • 所有的數值類型
  • string, bool, DateTime, DateTimeOffset, TimeSpan與Guid
  • 上述所有類型的Nullable<>版本

如果請求的名稱不存在的時候, 轉換到nullable類型在對於連帶著Element和Attribute的方法是非常有用的, 其轉換應該可以順利完成. 例如, 如果x沒有timeout元素, 第一行將會引起一個運行時錯誤, 而第二行則不會:

   1: int timeout = (int) x.Element ("timeout");   // 錯誤
   2: int? timeout = (int?) x.Element ("timeout"); // OK

我們可以使用??操作符來去除最後結果中的nullable類型. 以下的代碼在resolution屬性不存在的情況下將會返回1.0

   1: double resolution =
   2:   (double?) x.Attribute ("resolution") ?? 1.0;

不過, 如果element或者attribute存在並且包含一個空值(或者不正確的格式), 轉換到nullable類型並不會讓你就遠離麻煩. 上述情況, 你將會得到一個FormatException.

我們也可以在LINQ查詢中使用類型轉換. 例如以下的查詢返回”John”:

   1: var data = XElement.Parse (
   2:   @"<data>
   3:       <customer id='1' name='Mary' credit='100'  />
   4:       <customer id='2' name='John' credit='150'  />
   5:       <customer id='3' name='Anne' />
   6:     </data>");
   7:
   8: IEnumerable<string> query =
   9:   from cust in data.Elements( )
  10:   where (int?) cust.Attribute ("credit") > 100
  11:   select cust.Attribute ("name").Value;

轉換到一個nullable的int類型避免了NullReferenceException的產生(Anne沒有credit屬性). 另一種解決方案是給加一個斷言到where從句中.

   1: where cust.Attributes ("credit").Any()
   2: &&(int) cust.Attribute...

同樣的原則也可以應用於查詢元素的值.

值與混合的內容節點

由於有了Value屬性, 你可能會好奇什麼時候你才需要直接和XText節點打交道呢? 答案是: 當你擁有混合的內容的時候. 例如:

   1: <summary>
   2:   An XAttribute is <bold>not</bold> an XNode
   3: </summary>

一個簡單的Value屬性是不能夠獲取summary的全部內容的. summary元素包含了3個孩子:一個XText節點, 緊接著一個XElement, 然後再一個XText節點. 我們來看它是如何被構造的:

   1: XElement summary = new XElement ("summary",
   2:                       new XText ("An XAttribute is "),
   3:                       new XElement ("bold", "not"),
   4:                       new XText (" an XNode")
   5:                     );

有趣的是, 你依然還是可以查詢summary的Value值, 這並不會引起任何的異常. 相反, 我們獲得了每一個子節點的Value值的連接字符.

An XAttribute is not an XNode

重設summary的Value值也是合法的, 它將使用一個單一的XText節點替換前面提到的所子節點.

自動XText連接

當你增加簡單內容到一個XElement的時候, X-DOM將其添加到已存在的XText子節點中而不是去創建一個新的節點. 在下面的例子中, e1和e2最後形成了一個單一的XText元素, 其值是”HelloWorld”.

   1: var e1 = new XElement ("test", "Hello");
   2: e1.Add ("World");
   3:
   4: var e2 = new XElement ("test", "Hello", "World");

如果你指定要創建XText節點, 最終將會形成多個孩子節點:

   1: var e = new XElement ("test",
   2:                       new XText ("Hello"),
   3:                       new XText ("World"));
   4: Console.WriteLine (e.Value);             //  HelloWorld
   5: Console.WriteLine (e.Nodes( ).Count( ));  // 2

XElement不會自動連接兩個XText節點, 因此它們的對象身份是被保持的. 待續!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved