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.
[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
You could just use the System.Xml.Serialization.XmlSerializer
to deserialize it from xml to an object. Then if the element doesn't exist the property of the object will just get it's default value.
Have a look here: http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx or the new path https://docs.microsoft.com/en-us/dotnet/api/system.xml.serialization.xmlserializer
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";
You may use the code below:
string content = item.Element("Content") == null ? "" : item.Element("Content").Value;