简体   繁体   中英

LINQ reading XML …with XDocument

The following XML might contain Errors or not.
When it doesn't the result still outputs the < error >< / error> tag.

string xml = 
  "<response>
      <total>1</total>
      <bla>bla bla bla</bla>
      <error></error>
   </response>";

On my code I load the xml this way:

XDocument doc = XDocument.Parse(xml);  
XElement responseNode = doc.Element("response");

And parse for the Error tag this way:

List<Error> Errors = (from w in doc.Descendants("error")
           select new Error
           {
               ErrorCode = w.ElementValueInt("errorcode"),
               ErrorMessage = w.ElementValueString("errormessage")
           }).ToListSafely<Error>();

PROBLEM:
When there are NO errors, I still get Count = 1,
because the doc.Descendants("error") finds the the "< error>< /error>"

Is there a way to tell the LINQ code to EXCLUDE empty Nodes
when loading and parsing nodes ?

ANSWER:
I just needed to add the "where (w.HasElements)" on the LINQ, so

 List<Error> Errors = (from w in doc.Descendants("error")
       where (w.HasElements)
       select new Error
       {
           ErrorCode = w.ElementValueInt("errorcode"),
           ErrorMessage = w.ElementValueString("errormessage")
       }).ToListSafely<Error>();

...and it works !!!

It sounds like you really only want error elements which have subelements of errorcode and errormessage . How about this:

var errors = (from element in doc.Descendants("error")
              let code = (int?) element.Element("errorcode")
              let message = (string) element.Element("errormessage")
              where code != null && message != null
              select new Error {ErrorCode = code.Value, ErrorMessage = message})
             .ToList();

(I've guessed at what ElementValueInt and ElementValueString do, although I think the built-in conversions are probably a better idea. I don't know what ToListSafely does... it would help if you'd include this sort of thing...)

This way you won't end up creating an Error for an element such as:

<error><unrelated /></error>

You may filter out empty errors by using a where operator which checks the IsEmpty property of each XElement corresponding to an <error> :

List<Error> Errors = 
    (
        from w in doc.Descendants("error")
        where !w.IsEmpty
        select new Error
        {
            ErrorCode = w.ElementValueInt("errorcode"),
            ErrorMessage = w.ElementValueString("errormessage")
        }
    ).ToListSafely<Error>();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM