我正在尝试使用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
答案 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。
希望有所帮助!!!