2011-11-08 157 views
1

我有這樣的LINQ查詢:的LINQ to XML不知道節點

XNamespace ns = NAMESPACE; 

var items = (from c in doc.Descendants(ns +"Item") 
select new Item 
{ 
    Title = c.Element(ns + "ItemAttributes").Element(ns + "Title").Value, 
    MFR = c.Element(ns + "ItemAttributes").Element(ns + "Manufacturer").Value, 
    Offer = c.Element(ns + "Offers").Element(ns + "TotalOffers").Value, 
    Amazon = c.Element(ns + "Offer").Element(ns + "Merchant").Elements(ns + "MerchantId"), 
    LowPrice = Convert.ToDouble(c.Element(ns + "FormattedPrice").Value), 
    SalesRank = Convert.ToInt32(c.Element(ns +"SalesRank").Value), 
    ASIN = c.Element(ns + "ASIN").Value 
}).ToList<Item>(); 

它的偉大工程期待當一個節點不存在。例如,我沒有MFR或銷售排名。我該如何做到這一點,如果它沒有問題的節點,它給了我一個默認值或在我不試圖抓住我的整個查詢一個項目。

回答

3

據我所知的LINQ to XML不支持這一點。然而,我在我正在研究的一個項目中遇到了同樣的問題,併爲XElement創建了這個擴展來允許它。也許它會爲你工作:

public static XElement ElementOrDummy(this XElement parentElement, 
             XName name, 
             bool ignoreCase) 
{ 
    XElement existingElement = null; 

    if (ignoreCase) 
    { 
     string sName = name.LocalName.ToLower(); 

     foreach (var child in parentElement.Elements()) 
     { 
      if (child.Name.LocalName.ToLower() == sName) 
      { 
       existingElement = child; 
       break; 
      } 
     } 
    } 
    else 
     existingElement = parentElement.Element(name); 

    if (existingElement == null) 
     existingElement = new XElement(name, string.Empty); 

    return existingElement; 

} 

基本上它只是檢查是否該元素存在,如果沒有它返回一個具有相同的名稱和一個空值。

+0

對不起,原來的代碼片段,我張貼是不完整的。我已經編輯完整的擴展名。 –

+0

我更改爲'existingElement = new XElement(name,string.Empty);''existingElement = new XElement(name,「0」);'它對我的需求非常好! –

+0

真棒,很高興它幫助! –

0

如果XElement存在的問題,但值爲空?即

<Item> 
<ItemAttributes> 
    <Manufacturer></Manufacturer> 
    </ItemAttributes> 
</Item> 

,那麼你可以使用string.IsNullOrEmpty功能

XNamespace ns = NAMESPACE; 

var items = (from c in doc.Descendants(ns +"Item") 
select new Item 
{ 
    MFR = if (string.IsNullOrEmpty(c.Element(ns + "ItemAttributes").Element(ns + "Manufacturer").Value)) ? "default value here" : c.Element(ns + "ItemAttributes").Element(ns + "Manufacturer").Value, 
    // omitted for brevity 
}).ToList<Item>();