在不知道节点的情况下将LINQ转换为XML

本文关键字:LINQ 转换 XML 情况下 不知道 节点 | 更新日期: 2023-09-27 18:14:04

我有这个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或销售排名。我怎样才能使它,如果它没有问题的节点,它给我一个默认值,或者在非常不让我尝试捕捉我的整个查询一个项目。

在不知道节点的情况下将LINQ转换为XML

据我所知,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;
}

基本上它只是检查元素是否存在,如果不存在则返回一个同名且空值的元素

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

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

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

如果问题是XElement存在,但值为空?例如

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

则可以使用字符串。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>();