LINQ to XML而不知道节点

时间:2011-11-08 19:21:08

标签: c# xml linq-to-xml

我有这个LINQ查询:

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 个答案:

答案 0 :(得分: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;

}

基本上它只是检查元素是否存在,如果不存在则返回一个具有相同名称和空值的文件。

答案 1 :(得分:0)

您可以使用XElement显式转换,例如:

(int?)c.Element(ns +"SalesRank")

参考:http://msdn.microsoft.com/en-us/library/bb340386.aspx

答案 2 :(得分: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>();