Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if an element exists when parsing XML

Tags:

c#

xml

I'm parsing XML. I normally parse it the way I show in the code below which is straightforward The problem is that I don't own the XML I'm parsing and I can't change it. Sometimes there is no thumbnail element (there are no tags) and I get an Exception.

Is there a way to maintain this simplicity and check if the element exists? Or do I have to get first an XElement list with LINQ, to then check it and fill only the existing object properties?

void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    XDocument dataDoc = XDocument.Load(new StringReader(e.Result));

    var listitems = from noticia in dataDoc.Descendants("Noticia")
                    select new News()
                    {
                        id = noticia.Element("IdNoticia").Value,
                        published = noticia.Element("Data").Value,
                        title = noticia.Element("Titol").Value,
                        subtitle = noticia.Element("Subtitol").Value,
                        thumbnail = noticia.Element("Thumbnail").Value
                    };

    itemList.ItemsSource = listitems;
}
like image 406
enkara Avatar asked Mar 17 '11 08:03

enkara


People also ask

How do I check if an element exists in XML?

How to check if xml node exists? To verify if node or tag exists in XML content, you can execute an xpath expression against DOM document for that XML and count the matching nodes. matching nodes > zero – XML tag / attribute exists. matching nodes <= zero – XML tag / attribute does not exist.

How do you check if an element exists in the XML using XPath?

Use the fn:nilled XPath function to test whether the value of an input element has the xsi:nil attribute set. Use the fn:exists XPath function to test whether the value of an input element is present. Note: An XML element that has the xsi:nil attribute set is considered to be present.

How do you check if XML document is blank or has values?

You can try to load the XML into XML document and catch the exception. Here is the sample code: var doc = new XmlDocument(); try { doc. LoadXml(content); } catch (XmlException e) { // put code here that should be executed when the XML is not valid. }


2 Answers

[Edit]Jon Skeet's answer should be the accepted answer. It is far more readable and easier to apply.[/edit]

Create an extension method like this :

public static string TryGetElementValue(this XElement parentEl, string elementName, string defaultValue = null)  {     var foundEl = parentEl.Element(elementName);      if (foundEl != null)     {         return foundEl.Value;     }      return defaultValue; } 

then, change your code like this :

select new News() {     id = noticia.TryGetElementValue("IdNoticia"),     published = noticia.TryGetElementValue("Data"),     title = noticia.TryGetElementValue("Titol"),     subtitle = noticia.TryGetElementValue("Subtitol"),     thumbnail = noticia.TryGetElementValue("Thumbnail", "http://server/images/empty.png") }; 

This approach allows you to keep a clean code with isolating the check of element presence. It also allow you to define a default value, which can be helpful

like image 51
Steve B Avatar answered Sep 22 '22 17:09

Steve B


Instead of using the Value property, if you cast to string you'll just get a null reference instead:

void wc_DownloadStringCompleted(object sender,                                 DownloadStringCompletedEventArgs e) {     XDocument dataDoc = XDocument.Load(new StringReader(e.Result));      var listitems = from noticia in dataDoc.Descendants("Noticia")                     select new News()                     {                         id = (string) noticia.Element("IdNoticia"),                         published = (string) noticia.Element("Data"),                         title = (string) noticia.Element("Titol"),                         subtitle = (string) noticia.Element("Subtitol"),                         thumbnail = (string) noticia.Element("Thumbnail")                     };      itemList.ItemsSource = listitems; } 

That uses the explicit conversion from XElement to string, which handles a null input by returning a null output. The same is true for all explicit conversions on XAttribute and XElement to nullable types, including nullable value types such as int? - you just need to be careful if you're using nested elements. For example:

string text = (string) foo.Element("outer").Element("inner"); 

will give a null reference if inner is missing, but will still throw an exception if outer is missing.

If you want a "default" value, you can use the null coalescing operator (??):

string text = (string) foo.Element("Text") ?? "Default value"; 
like image 22
Jon Skeet Avatar answered Sep 21 '22 17:09

Jon Skeet