LINQ to XML, не зная узлов - PullRequest
       29

LINQ to XML, не зная узлов

1 голос
/ 08 ноября 2011

У меня есть этот запрос 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 ]

3 голосов
/ 08 ноября 2011

Насколько я знаю, 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 голосов
/ 08 ноября 2011

если проблема в том, что 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>();
0 голосов
/ 08 ноября 2011

Вы можете использовать явное преобразование XElement, например: * 1001.

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

Ссылка: http://msdn.microsoft.com/en-us/library/bb340386.aspx

...