当 .Count() 大于零时,从 .Select() 获取 NullReferenceException LINQ to XML

发布于 2024-12-22 09:09:36 字数 2414 浏览 1 评论 0原文

我有一个 XML 文件:

<Org href="https://vcloudserver/api/v1.0/org/272521719" type="application/vnd.vmware.vcloud.org+xml" name="blah-blah" xmlns="http://www.vmware.com/vcloud/v1">
     <Link href="https://vcloudserver/api/v1.0/vdc/1093121285" type="application/vnd.vmware.vcloud.vdc+xml" name="blah-haha" rel="down"/>
     <Link href="https://vcloudserver/api/v1.0/vdc/1213262741" type="application/vnd.vmware.vcloud.vdc+xml" name="blah-hoho" rel="down"/>
     <Link href="https://vcloudserver/api/v1.0/tasksList/272521719" type="application/vnd.vmware.vcloud.tasksList+xml" rel="down"/>
     <Link href="https://vcloudserver/api/v1.0/catalog/1309520800" type="application/vnd.vmware.vcloud.catalog+xml" name="blah-hehe" rel="down"/>
     <Link href="https://vcloudserver/api/v1.0/org/272521719/catalog/1309520800/controlAccess/" type="application/vnd.vmware.vcloud.controlAccess+xml" rel="down"/>
     <Link href="https://vcloudserver/api/v1.0/org/272521719/catalog/1309520800/action/controlAccess" type="application/vnd.vmware.vcloud.controlAccess+xml" rel="controlAccess"/>
     <Link href="https://vcloudserver/api/v1.0/network/1435818199" type="application/vnd.vmware.vcloud.network+xml" name="blah-whodat" rel="down"/>
     <Link href="https://vcloudserver/api/v1.0/network/2048048931" type="application/vnd.vmware.vcloud.network+xml" name="blah-disis" rel="down"/>
     <Description/>
     <FullName>Blah diddy Blah-Blah</FullName>
</Org>

所以,给出以下内容:

XNamespace nameSpace = "http://www.vmware.com/vcloud/v1";
var doc = XDocument.Parse(xml);

当我在 VS 立即窗口中调试以下代码时:

doc.Root.Elements(nameSpace + "Link").Count()

我得到一个预期值 8。但是当我进一步使用以下内容时:

var vdcs = doc.Root.Elements(nameSpace + "Link")
  .Select(x => new vDC()
  {
    Name = x.Attribute("name").Value,
    Type = x.Attribute("type").Value,
    Href = x.Attribute("href").Value
  }).Where(x=>x.Type.Contains("vdc"));

我收到一个 NullReferenceException 试图访问vdcs.Count()。我已经搞乱这个太久了......我在其他地方这种类型的东西工作得很好,所以这没有帮助。 :( 尝试在Where()之前填充ToList(),然后将NullReferenceException移动到该调用。

如果有帮助,vDC当前定义为:

public class vDC
{
  public string Name { get; set; }
  public string Type { get; set; }
  public string Href { get; set; }
}

I have an XML file:

<Org href="https://vcloudserver/api/v1.0/org/272521719" type="application/vnd.vmware.vcloud.org+xml" name="blah-blah" xmlns="http://www.vmware.com/vcloud/v1">
     <Link href="https://vcloudserver/api/v1.0/vdc/1093121285" type="application/vnd.vmware.vcloud.vdc+xml" name="blah-haha" rel="down"/>
     <Link href="https://vcloudserver/api/v1.0/vdc/1213262741" type="application/vnd.vmware.vcloud.vdc+xml" name="blah-hoho" rel="down"/>
     <Link href="https://vcloudserver/api/v1.0/tasksList/272521719" type="application/vnd.vmware.vcloud.tasksList+xml" rel="down"/>
     <Link href="https://vcloudserver/api/v1.0/catalog/1309520800" type="application/vnd.vmware.vcloud.catalog+xml" name="blah-hehe" rel="down"/>
     <Link href="https://vcloudserver/api/v1.0/org/272521719/catalog/1309520800/controlAccess/" type="application/vnd.vmware.vcloud.controlAccess+xml" rel="down"/>
     <Link href="https://vcloudserver/api/v1.0/org/272521719/catalog/1309520800/action/controlAccess" type="application/vnd.vmware.vcloud.controlAccess+xml" rel="controlAccess"/>
     <Link href="https://vcloudserver/api/v1.0/network/1435818199" type="application/vnd.vmware.vcloud.network+xml" name="blah-whodat" rel="down"/>
     <Link href="https://vcloudserver/api/v1.0/network/2048048931" type="application/vnd.vmware.vcloud.network+xml" name="blah-disis" rel="down"/>
     <Description/>
     <FullName>Blah diddy Blah-Blah</FullName>
</Org>

So, given the following:

XNamespace nameSpace = "http://www.vmware.com/vcloud/v1";
var doc = XDocument.Parse(xml);

When I debug the following code in VS immediate window:

doc.Root.Elements(nameSpace + "Link").Count()

I get an expected value, 8. But when I go a little further with things using:

var vdcs = doc.Root.Elements(nameSpace + "Link")
  .Select(x => new vDC()
  {
    Name = x.Attribute("name").Value,
    Type = x.Attribute("type").Value,
    Href = x.Attribute("href").Value
  }).Where(x=>x.Type.Contains("vdc"));

I am getting a NullReferenceException trying to access vdcs.Count(). I have been messing with this for too long... I have other places where this type of thing is working fine, so that doesn't help. :( Tried stuffing a ToList() before the Where(), and that just move the NullReferenceException up to that call.

If it helps, vDC is currently defined as:

public class vDC
{
  public string Name { get; set; }
  public string Type { get; set; }
  public string Href { get; set; }
}

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

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

发布评论

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

评论(2

暗恋未遂 2024-12-29 09:09:36

一些 Link 元素没有 name 属性,因此:

var vdcs = doc.Root.Elements(nameSpace + "Link")
  .Select(x => new vDC()
  {
    Name = x.Attribute("name").Value,
    Type = x.Attribute("type").Value,
    Href = x.Attribute("href").Value
  }).Where(x=>x.Type.Contains("vdc"));

令人窒息

Name = x.Attribute("name").Value

,因为在某些情况下 x.Attribute("name") 是 <代码>空。

var vdcs = doc.Root.Elements(nameSpace + "Link")
  .Select(x => new 
  {
    NameAttr = x.Attribute("name"),
    TypeAttr = x.Attribute("type"),
    HrefAttr = x.Attribute("href")
  }).Select(x => new vDC()
  {
    Name = x.NameAttr == null ? null : x.NameAttr.Value,
    Type = x.TypeAttr == null ? null : x.TypeAttr.Value,
    Href = x.HrefAttr == null ? null : x.HrefAttr.Value, 
  }).Where(x=>x.Type.Contains("vdc"));

或类似的应该解决问题。

Some of the Link elements have no name attribute, so:

var vdcs = doc.Root.Elements(nameSpace + "Link")
  .Select(x => new vDC()
  {
    Name = x.Attribute("name").Value,
    Type = x.Attribute("type").Value,
    Href = x.Attribute("href").Value
  }).Where(x=>x.Type.Contains("vdc"));

is choking on

Name = x.Attribute("name").Value

because in some cases x.Attribute("name") is null.

var vdcs = doc.Root.Elements(nameSpace + "Link")
  .Select(x => new 
  {
    NameAttr = x.Attribute("name"),
    TypeAttr = x.Attribute("type"),
    HrefAttr = x.Attribute("href")
  }).Select(x => new vDC()
  {
    Name = x.NameAttr == null ? null : x.NameAttr.Value,
    Type = x.TypeAttr == null ? null : x.TypeAttr.Value,
    Href = x.HrefAttr == null ? null : x.HrefAttr.Value, 
  }).Where(x=>x.Type.Contains("vdc"));

or similar should fix things.

ぃ弥猫深巷。 2024-12-29 09:09:36

您的某些链接没有名称 - 它们有rel。 NPE由此而来。

仅当您调用 Count 时才会看到它,因为在此之前不会进行实际评估。

要更改代码以防范 NPE,请添加 Where 条件:

var vdcs = doc.Root.Elements(nameSpace + "Link")
.Where(x => x.Attribute("name") != null && x.Attribute("type") != null && x.Attribute("value") != null)
.Select(x => new vDC {
    Name = x.Attribute("name").Value,
    Type = x.Attribute("type").Value,
    Href = x.Attribute("href").Value
}).Where(x=>x.Type.Contains("vdc"));

Some of your links don't have a name - they have rel instead. The NPE comes from that.

You see it only when you call Count because the actual evaluation does not happen until then.

To change your code to guard against NPE, add a Where condition:

var vdcs = doc.Root.Elements(nameSpace + "Link")
.Where(x => x.Attribute("name") != null && x.Attribute("type") != null && x.Attribute("value") != null)
.Select(x => new vDC {
    Name = x.Attribute("name").Value,
    Type = x.Attribute("type").Value,
    Href = x.Attribute("href").Value
}).Where(x=>x.Type.Contains("vdc"));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文