web-dev-qa-db-ja.com

XDocument&Linqを使用してXMLを読み取る-要素がNULLかどうかを確認しますか?

LINQとXDocumentを使用してXMLファイルを読み取ります。これはコードです:

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でクラッシュします。

「nullかどうかをチェック」を含める可能性はあるので、クラッシュを防ぐことができますか?

23
adchased

使用する (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")                   
        };

これは その他のデータ型 でも機能します。これには、要素が常に存在するとは限らない場合の多くのNULL入力可能型が含まれます。

42
dtb

「ヌル合体」演算子を使用できます。

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                   
        };

これにより、要素がない場合に使用されるデフォルト値を完全に制御できます。

8
Marqus

次の例を使用して、その要素を使用する前に要素の存在を確認します。

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

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();
1
Jayesh Sorathia