【问题标题】:Xml reader error: Object reference not set to an instance of an objectXML阅读器错误:对象引用未设置为对象的实例
【发布时间】:2016-04-27 22:57:16
【问题描述】:

我有大量包含doubleintDateTimestringlists of objects .. 等的 Xml 文件。混合了类似于此的变量类型:

<?xml version="1.0" encoding="utf-8"?>
<Verification xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <SerialNumber>1</SerialNumber>
  <Description>V1 From File</Description>
  <DateCreated>2016-04-22T09:27:54.193</DateCreated>
  <DesiredX>1.000000</DesiredX>
  <DesiredTargets count="3">
    <Sample X1="535.108154296875" X2="1058.36315917969" Y1="780.292175292969" Y2="1037.53625488281" A="-44.5051406645421" B="-2.8002082198978" C="-0.211281331705749" DifferenceA="-44.5051406645421" DifferenceB="-2.8002082198978" DifferenceC="-0.211281331705749" ReferenceNumber="0" TimeTaken="Tuesday, April 26, 2016 2:25:43 PM" />
    <Sample X1="529.666198730469" X2="533.695007324219" Y1="854.45654296875" Y2="514.573974609375" A="62.1131427426299" B="-4.93194374266585" C="-0.383094414887779" DifferenceA="62.1131427426299" DifferenceB="-4.93194374266585" DifferenceC="-0.383094414887779" ReferenceNumber="1" TimeTaken="Tuesday, April 26, 2016 2:25:43 PM" />
    <Sample X1="172.242752075195" X2="777.789245605469" Y1="334.160064697266" Y2="740.525268554688" A="9.54891420214495" B="91.256891073657" C="0.329283687878274" DifferenceA="9.54891420214495" DifferenceB="91.256891073657" DifferenceC="0.329283687878274" ReferenceNumber="2" TimeTaken="Tuesday, April 26, 2016 2:25:45 PM" />
  </DesiredTargets>
</Verification>

对象列表的类型为Sample,默认构造函数:

public Sample(Test targetTest, double newX1, double newX2, double newY1, double newY2, double newA, double newB, double newC, int sampleNum)

Class Verification,每个 Xml 文件都会被加载到它的一个实例中:

public class Verification
{
    public int SerialNumber { get; set; }
    public int ReferenceCount { get; set; }
    public string Description { get; set; }
    public DateTime DateCreated {get; set; }
    public double DesiredX { get; set; }
    public List<Sample> DesiredTargets { get; set; }
    // ..
    // other variables and functions
}

使命: 加载 Xml 文件

目的: 我不想更改每个文件的结构或标签以匹配 此处建议的某些代码模式Load in a simple list of objects

愿景

  • Xml 中不存在的任何变量,都应设置为null(默认情况下发生?)这里我知道targetTest 缺少参数,而Sample 构造函数需要该参数,但是如果我不知道缺少什么怎么办?我也知道ReferenceCountVerification 不在xml 中......等等。

  • 匹配文件的代码,而不是编辑所有文件以匹配代码

当我没有List&lt;Sample&gt; 时,我的代码使用XmlSerializer 工作。现在该文件有一个List&lt;Sample&gt;,下面的代码使用XDocument,但会弹出一个错误:

对象引用未设置为对象的实例

using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
// ..

public void LoadFromFile(string path)
{
    // stuff
    // ..
    // to load list of Sample
    XDocument XmlReader = XDocument.Load(path);

    // pops the error here
    DesiredTargets =
        XmlReader.Root.Elements("DesiredTargets")
        .Select(h => new Sample(
            null,
            double.Parse(h.Element("X1").Value),
            double.Parse(h.Element("X2").Value),
            double.Parse(h.Element("Y1").Value),
            double.Parse(h.Element("Y2").Value),
            double.Parse(h.Element("A").Value),
            double.Parse(h.Element("B").Value),
            double.Parse(h.Element("C").Value),
            int.Parse(h.Element("ReferenceNumber").Value)
            ))
        .ToList();

        // I don't have the code using XDocument for other variables yet but it works when there is no List<> using XmlSerializer
}

【问题讨论】:

  • @ Mephy 但这发生在我的应用程序加载之前。我不知道,所以我将对其进行编辑编辑:我只是注意到它可以编译,但此代码在应用程序加载时正确执行。我很困惑
  • 最好不要像为 XmlReader 所做的那样对变量使用 Pascal 大小写,因为它们很容易被其他开发人员甚至您或编译器混淆值规则类型。例如,.NET Framework 中实际上有一个 XmlReader 类。

标签: c# xml


【解决方案1】:

您的代码正在尝试使用h.Element("name").Value 读取DesiredTargets 的子元素。如果元素不存在,Element 返回null,对Value 属性的调用将抛出NullReferenceException

您尝试阅读的 7 个元素中没有一个实际存在,因此所有这些都会导致您看到的问题。它们不是元素,它们是Sample 元素的属性。顺便说一句,LINQ to XML 中有内置的显式转换,这意味着您不必解析字符串:

所以,这样的事情实际上会起作用:

doc.Descendants("DesiredTargets")
    .Elements("Sample")
    .Select(x => new Sample(
        null,
        (double)x.Attribute("X1"),
        (double)x.Attribute("X2"),
        (double)x.Attribute("Y1"),
        (double)x.Attribute("Y2"),
        (double)x.Attribute("A"),
        (double)x.Attribute("B"),
        (double)x.Attribute("C"),
        (int)x.Attribute("ReferenceNumber"))
    ).ToList();

也就是说,使用XmlSerializer 比自己手动编码序列化要好得多。 List&lt;T&gt; 应该不是问题。

【讨论】:

  • 为列表工作。谢谢!我现在还有一个问题,关于 Verification 类的其余变量,你能帮帮我吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-09
  • 2012-08-31
  • 2011-11-21
  • 2012-10-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多