使用linq从xml获取特定节点

时间:2011-08-10 15:52:08

标签: c# linq-to-xml

我在使用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而不是教室节点。有人可以帮我解决这个问题吗?

5 个答案:

答案 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节点时可能发生的任何异常。 (如果您在代码中的其他位置处理此异常,请忽略此项)

Enumerable.FirstOrDefault

答案 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)