我想使用XDocument访问XML文档中的一些深层结构。
为了避免NULL异常,所以我有很多IF检查,如
if(doc.Root.Element("E1") != null)
{
if(doc.Root.Element("E1").Element("E2") != null)
{
if(doc.Root.Element("E1")
.Element("E2")
.SingleOrDefault(e => e.Attribute("id") != null &&
e.Attribute("id").Equals("ABC")) != null)
{
var n = doc.Root
.Element("E1")
.Element("E2")
.SingleOrDefault(e => e.Attribute("id") != null &&
e.Attribute("id").Equals("ABC"))
.Attribute("name").Value;
}
}
}
实际结构更深入。我可以以某种方式消除这些NULL检查吗?
答案 0 :(得分:1)
您可以创建一个简单的扩展方法,该方法能够将投影应用于传播空值而不是抛出异常的可能为空的值:(请注意,不同的人喜欢为此操作使用不同的名称;随意调用方法对你来说最有意义。)
public static TResult Use<TSource, TResult>(
this TSource obj, Func<TSource, TResult> selector)
where TSource : class
where TResult : class
{
return obj == null ? null : selector(obj);
}
有了这个,您的代码可以压缩成以下内容:
var name = doc.Root.Element("E1")
.Use(element => element.Elements("E2"))
.Use(elements => elements.SingleOrDefault(
element => element.Attribute("id")
.Use(att => att.Value) == "ABC"))
.Use(element => element.Attribute("name").Value);
答案 1 :(得分:-1)
您不需要任何支票。您可以将属性转换为string
,然后使用==
检查相等性,而不是使用Equals
。
对于元素,您可以使用XPath
而不是像Root.Element("Foo").Element("Bar")
等单独选择它们。然后只检查XPath
查询的结果。这将需要 less < / em>至少检查......
另外值得注意的是,在C# 6
中会有一个Null propagating operator并允许您安全地访问对象的成员,然后您不需要任何这些检查。
答案 2 :(得分:-2)
你可以这样做:
var n = doc.Elements("E1").DefaultIfEmpty()
.Elements("E2").DefaultIfEmpty()
.FirstOrDefault(e => e!= null && e.Attribute("id") != null && e.Attribute("id").Equals("ABC"));
if (n != null) {
string s = n.Attribute("name").Value;
}