LINQ to XML:处理不存在的节点?

发布于 2024-08-14 04:29:40 字数 587 浏览 3 评论 0原文

这可能是一个简单的修复(嗯,可能是),但由于某种原因我就是无法弄清楚。

所以,我有一些看起来像这样的 xml:

XElement xml = XElement.Parse (
@"<Alphabet>
     <a name="A" />
     <b name="B" />
     <d name="D" />
     <e name="E" />
</Alphabet>");

所以稍后在我的代码中,我引用了一个可能存在也可能不存在的节点,如下所示:

var name = (from b in xml.Descendants("c")
            select b.Attribute("name")).FirstOrDefault().Value;

但是当它不存在时,它不会返回 null 或 "" 它会抛出NullReferenceException:未将对象引用设置为对象的实例。

检查并查看节点是否确实存在于我的 linq 查询中的最佳方法是什么?或者我需要以其他方式检查它是否存在?

This may be a simple fix (well, it probably is) but for some reason I just can't figure it out.

So, I have some xml that looks something like this:

XElement xml = XElement.Parse (
@"<Alphabet>
     <a name="A" />
     <b name="B" />
     <d name="D" />
     <e name="E" />
</Alphabet>");

So later in my code, I reference a node that may or may not exist in there like so:

var name = (from b in xml.Descendants("c")
            select b.Attribute("name")).FirstOrDefault().Value;

But when it doesn't exist, instead of returning null or "" it throws a NullReferenceException: Object reference not set to an instance of an object.

What's the best way to check and see if a node actually exists in my linq query? Or do I need to check if it exists some other way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

旧时光的容颜 2024-08-21 04:29:40

好吧,你正在选择属性 - 所以只需使用:(

var nameAttribute = xml.Descendants("c").Select(b => b.Attribute("name"))
                                        .FirstOrDefault();
if (nameAttribute != null)
{
    string name = nameAttribute.Value;
}
else
{
    // Whatever...
}

我已将其从查询表达式更改为点表示法,因为查询很简单 - 查询表达式语法实际上并没有给你带来任何东西。)

此解决方案的一个问题:它不区分存在“c”元素但不具有“name”属性,以及首先不存在“c”元素。您需要能够区分吗?

Well, you're selecting the attribute - so just use:

var nameAttribute = xml.Descendants("c").Select(b => b.Attribute("name"))
                                        .FirstOrDefault();
if (nameAttribute != null)
{
    string name = nameAttribute.Value;
}
else
{
    // Whatever...
}

(I've changed it from a query expression to dot notation because the query was trivial - query expression syntax wasn't actually buying you anything.)

One problem with this solution: it doesn't differentiate between there being a "c" element but it not having a "name" attribute, and there not being a "c" element in the first place. Do you need to be able to tell the difference?

私野 2024-08-21 04:29:40

我创建了扩展方法来为我做到这一点。

public static string GetAttributeValue(this XElement element, string attributeName)
{
    XAttribute attribute = element.Attribute(attributeName);
    return attribute != null ? attribute.Value : string.Empty;
}

public static string GetElementValue(this XElement element)
{
    return element != null ? element.Value : string.Empty;
}

public static string GetElementValue(this XElement element, string elementName)
{
    XElement child = element.Element(elementName);
    return child != null ? child.Value : string.Empty;
}

I created extension methods to do that for me.

public static string GetAttributeValue(this XElement element, string attributeName)
{
    XAttribute attribute = element.Attribute(attributeName);
    return attribute != null ? attribute.Value : string.Empty;
}

public static string GetElementValue(this XElement element)
{
    return element != null ? element.Value : string.Empty;
}

public static string GetElementValue(this XElement element, string elementName)
{
    XElement child = element.Element(elementName);
    return child != null ? child.Value : string.Empty;
}
尐偏执 2024-08-21 04:29:40

FirstOrDefault 返回 nullXAttribute,您可以将其转换为 string 以获取值:

var name = (string)((from b in xml.Descendants("c")
                     select b.Attribute("name")).FirstOrDefault());

var name = (string)xml.Descendants("c")
                      .Select(b => b.Attribute("name"))
                      .FirstOrDefault();

FirstOrDefault returns null or an XAttribute which you can cast to a string to get the value:

var name = (string)((from b in xml.Descendants("c")
                     select b.Attribute("name")).FirstOrDefault());

or

var name = (string)xml.Descendants("c")
                      .Select(b => b.Attribute("name"))
                      .FirstOrDefault();
野の 2024-08-21 04:29:40

您可以执行以下操作:

var name = (from b in xml.Descendants("c")
            select b.Attribute("name").Value).FirstOrDefault();

或者如果您确实需要该元素:

var name = (from b in xml.Descendants("c")
            select b.Attribute("name")).FirstOrDefault();

if (name != null)
{
    // your logic ...
}

You can do something like this:

var name = (from b in xml.Descendants("c")
            select b.Attribute("name").Value).FirstOrDefault();

or if you really need the element:

var name = (from b in xml.Descendants("c")
            select b.Attribute("name")).FirstOrDefault();

if (name != null)
{
    // your logic ...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文