有没有更好的方法来做这样的事情:
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
从XML文档解析元素/属性值时?在某些情况下,在执行以下操作时可能找不到该元素:
string foo (string)elem.Element("fooelement").Attribute("fooattribute").Value
因此会发生对象引用错误(假设未找到元素/属性)。尝试访问元素值时相同
答案 0 :(得分:5)
我只想使用扩展方法。它是一回事,但它更漂亮:
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);
}
然后你可以这样做:
string foo = element.SafeElement("fooelement").SafeAttribute("fooattribute").Value;
答案 1 :(得分:2)
不确定这是一种更好的方法,但我在CodeProject帖子中看到了它,并认为这可能是一种有用的方法。
使用“With”扩展方法的monadic解决方案:
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);
}
和返回扩展方法:
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);
}
将它们组合在一起您的查询可能如下所示:
var myElement = element.With(x => x.Element("FooElement")).Return(x => x.Attribute("FooAttribute").Value, "MyDefaultValue")
不确定它比使用之前帖子中已经建议的简单扩展方法更漂亮,但它更通用,是一个很好的方法IMO
答案 2 :(得分:1)
在C#6.0中,您可以使用monadic Null条件运算符?.
在您的示例中应用它之后,它将如下所示:
string foo = elem.Element("fooelement")?.Attribute("fooattribute")?.Value;
如果fooelement或fooattribute不存在,则整个表达式将导致null。您可以在标题为Null-conditional operators的部分中阅读更多here。
答案 3 :(得分:0)
尝试这种方式;
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;
}
}
然后更改代码:
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")
};