开发者

C# check an element exists while using LINQ to XML

OK, bit of a random question, but the best way to do this is to just add the code, you'll be able to see what I mean straight away:

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>
    <SuperTyp开发者_如何学JAVAe>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();

This comes up with a null error - would I need to add the "SuperType" element to each customer before it with a null value, or is there a workaround that would mean I don't have to do that?

Cheers!


Try this:

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

Basically if you cast a null XElement reference to string, you'll get a null reference (which you can compare with "1").

An alternative would be to cast to int? which (IIRC) will return a null int? value if the element is missing, but go bang if it's present but non-numeric:

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


You should be able to just add a check for null

where c.Element("SuperType") != null 
&& [your other criteria]


Have you tried checking if the SuperType element exists before trying to read the value from it?

...
where (c.Element("SuperType") != null && c.Element("SuperType").Value == "1")
...


I would do it like this:

var superType = linquee.Descendants("customer").
    Where(c => c.Element("SuperType") != null 
        && c.Element("SuperType").Value == "1");


Should also be able to clean this kinda stuff up with extensions, something like..

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

and then just:

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


I found a nice solution using Any() in combination with a conditional operator:

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

The trick is to use Elements() together with Any() to check if the element exists (same for Attributes())

So for this example it would be something like this:

var superType = from c in linquee.Descendants("customer")  
                select c.Elements("SuperType").Any() ? c.Element("SuperType").Value : "0";
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜