我在使用linq查询到xml树时遇到了一些麻烦。这是树结构的样子:
<Student>
<ID> Hello </Hello>
<Classroom>
<Name> 1B </Name>
<Year> 1 </Year>
</Classroom>
<Classroom>
<Name> 2B </Name>
<Year> 2 </Year>
</Classroom>
<Classroom>
<Name> 3B </Name>
<Year> 3 </Year>
</Classroom>
</Student>
现在这是5中的一个学生条目。说我从另一个方法传递了XElement学生节点,我想在给定XElement学生节点和教室名称的情况下搜索教室。所以我必须写一个这样的方法:
getClassRoomNode(XElement StudentNode, string classroomName)
这是我尝试过的。请让我知道我错在哪里
XElement classroom = StudentNode.Descendants("Classroom")
.Where(arg => arg.Element("Name").Value == classroomName)
.Select(arg => arg.Parent)
.First();
这将再次返回StudentNode而不是教室节点。有人可以帮我解决这个问题吗?
答案 0 :(得分:2)
您无需选择父级,只需获取First()
或更好的Single()
教室。
XElement classroom = StudentNode.Descendants("Classroom")
.Single(arg => arg.Element("Name").Value == classroomName);
我建议错误而不是忽略后续匹配更好。如果意图是匹配许多比赛的第一个,那么显然,
XElement classroom = StudentNode.Descendants("Classroom")
.First(arg => arg.Element("Name").Value == classroomName);
答案 1 :(得分:1)
摆脱选择,你正在重新选择父母!
XElement classroom = StudentNode.Descendants("Classroom").Where(arg => arg.Element("Name").Value == classroomName).First();
答案 2 :(得分:1)
您的代码完全符合其要求:选择&lt; classrom&gt; name元素的内容等于 classroomName 的节点,然后选择该元素的父级&lt; classrom&gt;节点,即&lt; student&gt;节点
修正:
XElement classroom =
StudentNode.Elements("Classroom")
.First(arg => (string)arg.Element("Name") == classroomName);
这将返回第一个&lt; classrom&gt; name元素的内容等于 classroomName 的节点。
答案 3 :(得分:0)
您正在选择“课堂”节点的父节点。像这样更改查询:
XElement classroom = StudentNode.Descendants("Classroom").First(arg => arg.Element("Name").Value == classroomName);
除了使用First之外,您应该使用FirstOrDefault并检查空值以阻止在根据您的查询找不到Classroom节点时可能发生的任何异常。 (如果您在代码中的其他位置处理此异常,请忽略此项)
答案 4 :(得分:0)
这是因为您正在选择教室节点的父级。摆脱最后一个选择器:
XElement classroom = StudentNode.Descendants("Classroom").Where(arg => arg.Element("Name").Value == classroomName).First();
甚至更简单,正如所指出的那样将First和Where结合在一起。
XElement classroom = StudentNode.Descendants("Classroom").First(arg => arg.Element("Name").Value == classroomName)
如果没有匹配,这将抛出异常,另一方面,FirstOrDefault将在不匹配时返回null;
XElement classroom = StudentNode.Descendants("Classroom").FirstOrDefault(arg => arg.Element("Name").Value == classroomName)