元素提取返回null

时间:2015-01-06 17:21:24

标签: c# linq-to-xml

我正在尝试使用Linq-to-XML来缩短我的代码并使其更具可读性,但是我遇到了一个错误,我一直得到一个null。我正在尝试使以下代码工作:

var listOfFoos = new List<FooItem>();
var xdoc = XDocument.Parse(fooData);
var fooNodes = xdoc.Descendants("Foo");
var foos = fooNodes.Select(f => new FooItem()
            {
                x = f.Element("X").Value,
                y = float.Parse(f.Element("Y").Value),
                z = int.Parse(f.Element("Z").Value)
            });
foreach(var foo in foos)
{
    listOfFoos.Add(foo);
}

但是当我尝试使用foos或在VS中打开结果视图时,我得到一个空错误或“对象未设置为引用”。从Linq-to-XML备份,我编写了以下完全正常的代码:

var listOfFoos = new List<FooItem>();
var xdoc = XDocument.Parse(fooData);
var foos = xdoc.Descendants("Foo").ToList();
foreach (var f in foos)
{
     var foo = new FooItem();
     foo.x = f.Element("X").Value;
     foo.y = float.Parse(f.Element("Y").Value);
     foo.z = int.Parse(f.Element("Z").Value);
     listOfFoos.Add(s);
}

那么是什么阻止了Linq-to-XML的工作而我的第二个实现顺利完成呢?

XML看起来像这样:

<Foos>
    <Foo>
        <X>AFE3-JJ-WO2N-353E</X>
        <Y>3341.3426661</Y>
        <Z>10</Z>
    </Foo>
    <Foo>
        <X>30IE-N2-IIS2-WER4</X>
        <Y>154.558921</Y>
        <Z>5</Z>
    </Foo>
    ...
</Foos>

这是FooItem类:

public class FooItem
{
    public string X { get; set; }
    public float Y { get; set; }
    public int Z { get; set; }
}

我得到了错误的堆栈跟踪:

"Object reference not set to an instance of the object."
   at SigCaptureWeb.Controllers.HomeController.<RetrievePDF>b__1(XElement f) in c:\Users\ams\Documents\Visual Studio 2013\Projects\SigCapture\SigCaptureWeb\Controllers\HomeController.cs:line 101
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at SigCaptureWeb.Controllers.HomeController.RetrievePDF(String formCode, String dataXML) in c:\Users\ams\Documents\Visual Studio 2013\Projects\SigCapture\SigCaptureWeb\Controllers\HomeController.cs:line 108

2 个答案:

答案 0 :(得分:0)

我在此代码中未发现任何问题,请验证是否需要更改。

 string fooData = @"<Foos>
                     <Foo>
                       <X>AFE3-JJ-WO2N-353E</X>
                       <Y>3341.3426661</Y>
                       <Z>10</Z>
                     </Foo>
                     <Foo>
                      <X>30IE-N2-IIS2-WER4</X>
                      <Y>154.558921</Y>
                      <Z>5</Z>
                     </Foo>
                   </Foos>";
        var listOfFoos = new List<FooItem>();
        var xdoc = XDocument.Parse(fooData);
        var fooNodes = xdoc.Descendants("Foo");
        var foos = fooNodes.Select(f => new FooItem()
        {
            X = f.Element("X").Value,
            Y = float.Parse(f.Element("Y").Value),
            Z = int.Parse(f.Element("Z").Value)
        });
        foreach (var foo in foos)
        {
            listOfFoos.Add(foo);
        }

答案 1 :(得分:-1)

它显然看起来你有错误的xml可能没有标签中的值或错误的类型值,你可以做些什么来处理/检查错误是什么

 internal class FooItem  
    {
        public FooItem(XElement xElement)
        {
            float yvar = -1;
            int zvar = -1;
            if (xElement.Element("X") == null) X = "";
            else X = xElement.Element("X").Value;

            if (xElement.Element("Y") == null) Y = yvar;
            else
            {
                if (float.TryParse(xElement.Element("Y").Value, out yvar))
                    Y = yvar;
            }

            if (xElement.Element("Z") == null) Z = zvar;
            else
            {
                if (int.TryParse(xElement.Element("Z").Value, out zvar))
                    Z = zvar;
            }

        }

        public string X { get; set; }
        public float Y { get; set; }
        public int Z { get; set; }
    }

然后在你的投影中调用构造函数,就像这样..

  var foos = fooNodes.Select(f => new FooItem(f));

这里的构造函数将确保进行健全性检查,如果XML中出现错误值,则放置0或-1。

希望有所帮助!!!