2010-04-07 113 views
22

我使用LINQ和XDocument一起读取XML文件。这是代码:使用XDocument&Linq读取XML - 检查元素是否为NULL?

XDocument xml = XDocument.Load(filename); 

var q = from b in xml.Descendants("product") 
     select new 
     { 
      name = b.Element("name").Value, 
      price = b.Element("price").Value,      
      extra = b.Element("extra1").Value, 
      deeplink = b.Element("deepLink").Value     
     }; 

现在的问题是,在extra1领域并不总是存在。没有该节点的XML文件中有项目。如果发生这种情况,它会与NullReferenceException一起崩溃。

有没有可能包含“检查是否为空”,以便我可以防止它崩溃?

回答

41

使用(string)代替.Value

var q = from b in xml.Descendants("product") 
     select new 
     { 
      name = (string)b.Element("name"), 
      price = (double?)b.Element("price"),      
      extra = (string)b.Element("extra1"), 
      deeplink = (string)b.Element("deepLink")     
     }; 

这也适用于other datatypes,其中包括许多可空类型的情况下,该元素并不总是存在。

+5

+1 - 有趣。 – womp 2010-04-07 17:39:52

7

您可以使用“空合并”运营商:

var q = from b in xml.Descendants("product") 
     select new 
     { 
      name = (string)b.Element("name") ?? "Default Name", 
      price = (double?)b.Element("price") ?? 0.0,      
      extra = (string)b.Element("extra1") ?? String.Empty, 
      deeplink = (string)b.Element("deepLink") ?? String.Empty     
     }; 

这种方式,你将有大约当没有元素使用默认值完全控制。

+2

'价格'需要是'双重',因为这条线是有意义的。 – AakashM 2010-04-08 06:38:45

1

以下是使用XDocument读取XML文件的示例示例。

XDocument objBooksXML = XDocument.Load(Server.MapPath("books.xml")); 
    var objBooks = from book in 
        objBooksXML.Descendants("Book") 
        select new { 
           Title = book.Element("Title").Value, 
           Pages = book.Element("Pages").Value 
           }; 

    Response.Write(String.Format("Total {0} books.", objBooks.Count())); 
    gvBooks.DataSource = objBooks; 
    gvBooks.DataBind(); 
+0

这段代码的问题在于,如果“Book”不包含“标题”或“页面”元素,则在尝试从其中任何一个获取.Value时,会抛出空异常。 – Bil 2014-01-01 18:11:58

2

使用以下示例在使用该元素之前检查是否存在任何元素。

if(b.Elements("extra1").Any()) 
{ 
    extra = b.Element("extra1").Value; 
}