C # проверить элемент существует при использовании LINQ to XML - PullRequest
9 голосов
/ 13 апреля 2010

ОК, немного случайный вопрос, но лучший способ сделать это - просто добавить код, и вы сразу поймете, что я имею в виду:

XML:

<?xml version="1.0" encoding="utf-8" ?>
<customers>
  <customer>
    <id>1</id>
    <name>Blah-face</name>
    <Type>1</Type>
  </customer>
  <customer>
    <id>2</id>
    <name>Blah-face-2</name>
    <Type>2</Type>
  </customer>
  <customer>
    <id>3</id>
    <name>Blah-face-3</name>
    <Type>1</Type>
    <SuperType>1</SuperType>
  </customer>
</customers>

C #:

XDocument linquee = XDocument.Load(path);

var superType = (from c in linquee.Descendants("customer")
                 where (c.Element("SuperType").Value == "1")
                 select c).ToList();

Это приводит к ошибке NULL - нужно ли добавлять элемент «SuperType» каждому клиенту перед его значением NULL, или есть обходной путь, который бы означал, что мне не нужно это делать? *

Ура!

Ответы [ 6 ]

13 голосов
/ 13 апреля 2010

Попробуйте это:

var superType = (from c in from c in linquee.Descendants("customer")
                 where (string) c.Element("SuperType") == "1"
                 select c).ToList();

Обычно, если вы приведете нулевую ссылку XElement к string, вы получите нулевую ссылку (которую можно сравнить с «1»).

Альтернативой может быть приведение к int?, которое (IIRC) вернет нулевое значение int?, если элемент отсутствует, но с ударом, если он присутствует, но не числовой:

var superType = (from c in from c in linquee.Descendants("customer")
                 where (int?) c.Element("SuperType") == 1
                 select c).ToList();
6 голосов
/ 13 апреля 2010

Вы можете просто добавить проверку на ноль

where c.Element("SuperType") != null 
&& [your other criteria]
3 голосов
/ 13 апреля 2010

Вы пытались проверить, существует ли элемент SuperType, прежде чем пытаться прочитать значение из него?

...
where (c.Element("SuperType") != null && c.Element("SuperType").Value == "1")
...
0 голосов
/ 10 июня 2012

Я нашел хорошее решение, используя Any () в сочетании с условным оператором:

result = entry.Elements(ArbitraryElement).Any() ? (entry.Element(ArbitraryElement).Attributes(ArbitraryAttribute).Any() ? entry.Element(ArbitraryElement).Attribute(ArbitraryAttribute).Value : "-1") : "-1"

Хитрость в том, чтобы использовать Elements () вместе с Any (), чтобы проверить, существует ли элемент (то же самое для Attributes ())

Так что для этого примера это будет примерно так:

var superType = from c in linquee.Descendants("customer")  
                select c.Elements("SuperType").Any() ? c.Element("SuperType").Value : "0";
0 голосов
/ 24 июня 2010

Должен также быть в состоянии убрать такие вещи с расширениями, что-то вроде ..

public string Element_valStr(XElement xElm, string xName)
{
    if (xElm.Element(xName) == null) return string.empty;
    return xElm.Element(xName).Value;
}

, а затем просто:

var superType = (from c in linquee.Descendants("customer")  
                  where (c.Element_valStr("SuperType") == "1")
                  select c).ToList();
0 голосов
/ 13 апреля 2010

Я бы сделал это так:

var superType = linquee.Descendants("customer").
    Where(c => c.Element("SuperType") != null 
        && c.Element("SuperType").Value == "1");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...