【问题标题】:IOrderedEnumerable<XElement> returning NullReferenceExceptionIOrderedEnumerable<XElement> 返回 NullReferenceException
【发布时间】:2013-07-12 14:54:23
【问题描述】:

我目前遇到的问题是通过以下方法获得 NullReferenceException:

    public void LoadValueXML()
    {
        XDocument myxml = XDocument.Load(@"config.xml");
        Items = myxml.Element("Values").Elements("Item").OrderBy(x => x.Attribute("ID"));
        ItemsLength = Items.Count();
    }

我尝试设置 Items 变量的方法的第四行正在生成异常。我的 XML 文档格式如下:

<?xml version="1.0" encoding="utf-8" ?>
<Values>
  <Item ID="1" Type="Command" Value="330MV,60HZ"/>
  <Item ID="2" Type="Command" Value="600MV,13KHZ"/>
  <Item ID="3" Type="Command" Value="3.3V,60HZ"/>
  <Item ID="4" Type="Notification" Value="Look At This!!!" />
</Values>

我似乎找不到问题所在。看起来一切都很好地加载到 XDocument 中。在调试器中,它显示 XDocument 不为空,但是当我尝试设置 Items 时,它仍然会引发异常。提前感谢您为解决此问题提供的任何帮助。

附带说明:尝试使用 XDocument.Parse() 而不是 XDocument.Load() 会返回 "Data at the root level is invalid. Line 1, position 1." 异常。

编辑:

在听从 cdhowie 的建议后,我目前的方法如下所示:

    public void LoadValueXML()
    {
        XDocument myxml = XDocument.Load(@"config.xml");
        var values = myxml.Element("Values");
        var items = values.Elements("Item");
        Items = items.OrderBy(x => x.Attribute("ID"));
        ItemsLength = Items.Count();
    }

values 为 null 并且项目正在返回“枚举未产生任何结果”。它不再抛出异常,但仍然无法正常工作。

编辑 2:

遵循 Jeyaram J 建议的新方法:

    public void LoadValueXML()
    {
        XDocument myxml = XDocument.Load(@"config.xml");
        var items = myxml.Root.Elements("Item");
        Items = items.OrderBy(x => x.Attribute("ID"));
        ItemsLength = Items.Count();
    }

它可以部分工作,但会抛出“至少一个对象必须实现 IComparable”。例外。

【问题讨论】:

  • 关于 Parse() 与 Load():文档开头是否有 UTF-8 BOM?也许 Load() 在将 BOM 提供给解析器之前将其剥离,但无论您使用什么将文件加载到字符串中,都不会将其剥离。
  • Parse() 用于 XML 本身作为字符串。
  • 您需要将 x.Attribute("ID").Value 解析为整数。看看我的回答

标签: c# wpf xml


【解决方案1】:

尝试使用 Root 而不是 Element。

public void LoadValueXML()
{
    XDocument myxml = XDocument.Load("config.xml");
    Items = myxml.Root.Elements("Item").OrderBy(x => (int)x.Attribute("ID"));
    ItemsLength = Items.Count();
}

如果它不起作用,请告诉我

【讨论】:

  • 这至少部分有效。它抛出一个错误“至少一个对象必须实现 IComparable。”
  • @ZachSmith 由​​于这是最接近的,我将修改他的而不是创建几乎完全相同的答案。在x.Attribute("ID") 之前添加(int) 以将属性转换为整数。
  • @ZachSmith 您需要 IComparable 的原因是 OrderBy 不知道如何自动对 Attribute 进行排序,但它可以处理整数。
【解决方案2】:

在调试这样的事情时,请考虑将每个链接的方法调用分解为自己的语句。

var values = myxml.Element("Values");
var items = values.Elements("Item");
Items = items.OrderBy(x => x.Attribute("ID"));

异常指向的行现在应该清楚地表明哪个方法返回 null,您还可以在调试器中检查本地变量来验证这一点。

【讨论】:

  • 真正奇怪的是这并没有抛出异常。它有效。
  • @ZachSmith 即使你添加了ItemsLength = Items.Count(); ?
  • 看来它只是没有抛出异常。我运行了调试器,值设置为 null,一旦方法运行,Items 为空。
  • @ZachSmith 首先,尝试在 OrderBy 的末尾添加一个 ToList()。告诉我们会发生什么。
  • 添加了 ToList()。仍然得到“枚举没有结果”。
【解决方案3】:

您应该在按属性订购时添加.Value。你想按ID 的值排序,不是吗?

奇怪的是,我有一个 ArgumentException 和你的代码 (at least one object must implement IComparable),而不是 NRE...

Items = myxml.Element("Values")
             .Elements("Item")
             .OrderBy(x => x.Attribute("ID").Value);

或者如果你想要数字排序

OrderBy(x => Convert.ToInt32(x.Attribute("ID").Value);

【讨论】:

  • 它仍然抛出同样的错误。最远的 InnerException 仍然是“对象引用未设置为对象的实例。”
  • 我按照 cdhowie 的建议将其拆分,然后 NRE 消失了。奇怪...现在我只是好奇是什么原因造成的。
  • @ZachSmith 所以你遇到了ItemsItemsLength 的问题,而不是xml 解析......它们来自哪里?
  • 用我的代码(没有ToList())测试了这些变量,它运行良好。您确定给定的 Xml 是您使用的那个吗?
  • @ZachSmith 这是我在回答中遇到的错误。添加.Value
【解决方案4】:

每当我调试意外的 LINQ 问题时,我的第一步通常是分解每个单独的步骤。例如:

var document = XDocument.Load(@"config.xml");
var valuesElement = document.Element("Values");
var itemElements = valuesElement.Elements("Item");
var idAttributes = itemElements.Select(x => x.Attribute("ID"));
var orderedItems = itemElements.OrderBy(x => x.Attribute("ID"));
var orderedItemsCount = orderedItems.Count();

像你已经在做的那样在调试器中单步执行通常会揭示根本问题。

【讨论】:

    【解决方案5】:
            public void loadXMl()
            {
                string abcd = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
    <Values>
      <Item ID=""1"" Type=""Command"" Value=""330MV,60HZ""/>
      <Item ID=""2"" Type=""Command"" Value=""600MV,13KHZ""/>
      <Item ID=""3"" Type=""Command"" Value=""3.3V,60HZ""/>
      <Item ID=""4"" Type=""Notification"" Value=""Look At This!!!"" />
    </Values>";
    
                XDocument myxml = XDocument.Load(abcd);//Parse(abcd);
                var Items = myxml.Element("Values");
               var abc =   Items.Elements("Item");
                var ordered =   abc.OrderBy(x => int.Parse(x.Attribute("ID").Value));
                var ItemsLength = ordered.Count();
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-21
      • 2010-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-21
      • 1970-01-01
      相关资源
      最近更新 更多