Behandeln von null XElements beim Analysieren eines XDocuments - c #, xml, Fehlerbehandlung, linq-to-xml

Gibt es einen besseren Weg, so etwas zu tun:

private XElement GetSafeElem(XElement elem, string key)
{
XElement safeElem = elem.Element(key);
return safeElem ?? new XElement(key);
}

private string GetAttributeValue(XAttribute attrib)
{
return attrib == null ? "N/A" : attrib.Value;
}

var elem = GetSafeElem(elem, "hdhdhddh");
string foo = GetAttributeValue(e.Attribute("fkfkf"));

//attribute now has a fallback value

Beim Parsen von Elementen / Attributwerten aus einem XML-Dokument? In einigen Fällen wird das Element möglicherweise nicht gefunden, wenn Sie Folgendes tun:

string foo (string)elem.Element("fooelement").Attribute("fooattribute").Value

Es würde also ein Objektreferenzfehler auftreten (vorausgesetzt, dass das Element / Attribut nicht gefunden wurde). Gleiches, wenn versucht wird, auf den Elementwert zuzugreifen

Antworten:

2 für die Antwort № 1

Ich bin mir nicht sicher, ob dies ein besserer Ansatz ist, aber ich habe es in einem CodeProject-Beitrag gesehen und dachte, dass es hier ein nützlicher Ansatz sein könnte.

Es ist eine monadische Lösung mit einer Erweiterungsmethode "Mit":

public static TResult With<TInput, TResult>(this TInput o,
Func<TInput, TResult> evaluator)
where TResult : class where TInput : class
{
if (o == null) return null;
return evaluator(o);
}

und eine Rückkehrverlängerungsmethode:

public static TResult Return<TInput,TResult>(this TInput o,
Func<TInput, TResult> evaluator, TResult failureValue) where TInput: class
{
if (o == null) return failureValue;
return evaluator(o);
}

Und wenn Sie beide zusammen kombinieren, könnte Ihre Abfrage wie folgt aussehen:

var myElement = element.With(x => x.Element("FooElement")).Return(x => x.Attribute("FooAttribute").Value, "MyDefaultValue")

Nicht sicher, dass es hübscher als die Verwendung der einfachen Erweiterung Methoden die Jungs bereits in früheren Posts vorgeschlagen, aber es ist ein bisschen generischer und ist ein guter Ansatz IMO

CodeProject - Chained-Null-Checks und die Maybe-Monade


5 für die Antwort № 2

Ich würde nur Erweiterungsmethoden verwenden. Es ist das Gleiche, aber es ist schöner:

public static XElement SafeElement(this XElement element, XName name)
{
return element.Element(name) ?? new XElement(name);
}

public static XAttribute SafeAttribute(this XElement element, XName name)
{
return element.Attribute(name) ?? new XAttribute(name, string.Empty);
}

Dann können Sie tun:

string foo = element.SafeElement("fooelement").SafeAttribute("fooattribute").Value;

1 für die Antwort № 3

In C # 6.0 können Sie den monadischen Null-Bedingungsoperator verwenden ?. Nach dem Anwenden in Ihrem Beispiel würde es so aussehen:

string foo = elem.Element("fooelement")?.Attribute("fooattribute")?.Value;

Wenn fooelement oder fooattribute nicht existiert, würde der ganze Ausdruck zu null führen. Sie können mehr lesen Hier teilweise mit dem Titel Null-bedingte Operatoren.


0 für die Antwort № 4

Versuche es auf diese Weise;

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

und dann den Code wie folgt ändern:

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")
};

Speisekarte