我目前正在研究XML并在C#中使用它并将其与LINQ一起使用。
我有以下
我的XML文件
<RECSTEPS>
<RECSTEPS1>
<STEP>Step 1 - prepare</STEP>
<STEP>Step 2 - cut</STEP>
</RECSTEPS1>
<RECSTEPS2>
<STEP>Step 1 - prepare</STEP>
<STEP>Step 2 - cut</STEP>
<STEP>Step 3 - Weld</STEP>
</RECSTEPS2>
<RECSTEPS3>
<STEP>Step 1 - prepare</STEP>
<STEP>Step 2 - cut</STEP>
</RECSTEPS3>
</RECSTEPS>
我使用的代码如下:
string strFileName=@"\\wlfp02\home\CS4\nsavidge\Work\XML\test2.xml";
XDocument xd = XDocument.Load(strFileName);
var t = xd.Descendants("RECSTEPS2");
foreach (XElement xe in t.Elements())
{
Console.WriteLine(xe.Value);
}
这很好,但是,我正在尝试使用LINQ来做同样的事情。我得到了相同的数量,但是无法接受我的输出,即可数内的数字。我看过手表,但不能确定。
var t2 = xd.Root.Elements().Select(o => o.Element("RECSTEPS2"));
由于
答案 0 :(得分:0)
你的代码错了。它应该是:
var t2 = xd.Descendants("RECSTEPS2")
.SelectMany(e => e.Elements());
在您的查询中,您将根节点的每个元素投影到RECSTEPS2
元素的值。换句话说,您的查询将返回与根节点下的元素数量一样多的元素RECSTEPS2
的副本。
你在想的是过滤,即使用Where
运算符,如下所示:
var t2 = xd.Root.Elements()
.Where(e => e.Name == "RECSTEPS2");
但是上面会给你一个IEnumerable<XElement>
,它符合元素RECSTEPS2
的标准(尽管只有一个)。
换句话说,使用上面的代码迭代RECSTEPS2
的子元素,你需要一个双循环:
foreach(var parent in t2)
foreach(var child in parent)
Console.WriteLine(child.Value);
使用SelectMany
的好处是它可以展平元素的层次结构,只给出RECSTEPS2
节点的子元素,这样您的完整代码就会如下所示:
var t2 = xd.Descendants("RECSTEPS2")
.SelectMany(e => e.Elements());
foreach(var xe in t2)
Console.WriteLine(xe.Value);
// Will print
// Step 1 - prepare etc
答案 1 :(得分:0)
首先,帮自己一个忙,得到Linqpad。它允许您使用Linq查询并立即获得您的查询正在进行的视觉反馈。
将代码直接翻译为Linq
是:
IEnumerable<string> stepTwoSteps = xd.Root
.Descendants("RECSTEPS2")
.Elements()
.Select (rs2 => rs2.Value);
foreach(string stepValue in stepTwoSteps)
{
Console.WriteLine(stepValue);
}
有些事情需要考虑:
Elements("RECSTEPS2")
代替Descendants("RECSTEPS2")
,因为后者搜索XML结构的所有深度,前者仅在其使用的节点下立即查看我猜你正在寻找更多的东西:
var stepTwoSteps = xd.Root
.Elements("RECSTEPS2")
.Elements("STEP")
.Select (step => step.Value)
foreach(string stepValue in stepTwoSteps)
{
Console.WriteLine(stepValue);
}