Получение определенного узла из xml с использованием linq - PullRequest
2 голосов
/ 10 августа 2011

У меня возникли проблемы с запросом 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 Student из другого метода, и я хочу найти классную комнату, учитывая XElement Studentузел и название класса.Поэтому я должен написать такой метод:

getClassRoomNode(XElement StudentNode, string classroomName)

Это то, что я пробовал.Пожалуйста, дайте мне знать, где я ошибаюсь

XElement classroom = StudentNode.Descendants("Classroom")
                                .Where(arg => arg.Element("Name").Value == classroomName)
                                .Select(arg => arg.Parent)
                                .First();

Это снова возвращает StudentNode вместо узла класса.Может кто-нибудь помочь мне с этим?

Ответы [ 5 ]

2 голосов
/ 10 августа 2011

Вам не нужно выбирать родителя, просто получите класс 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 голос
/ 10 августа 2011

Ваш код выполняет в точности то, что ему сказано: выберите узел , где содержимое элемента name равно classroomName , а затем выберите родительский элемент этого узла , то есть узел.

Fix:

XElement classroom =
    StudentNode.Elements("Classroom")
               .First(arg => (string)arg.Element("Name") == classroomName);

Возвращает первый узел, в котором содержимое элемента name равно classroomName .

1 голос
/ 10 августа 2011

Избавьтесь от выбора, вы снова выбираете родителя!

XElement classroom = StudentNode.Descendants("Classroom").Where(arg => arg.Element("Name").Value == classroomName).First();
0 голосов
/ 10 августа 2011

Это потому, что вы выбираете родителя узлов класса. Просто избавьтесь от последнего селектора:

XElement classroom = StudentNode.Descendants("Classroom").Where(arg => arg.Element("Name").Value == classroomName).First();

Или даже проще, как было указано, объединить Сначала и Где вместе.

XElement classroom = StudentNode.Descendants("Classroom").First(arg => arg.Element("Name").Value == classroomName)

Это, однако, вызовет исключение, если совпадения нет, FirstOrDefault с другой стороны вернет ноль при отсутствии совпадения;

XElement classroom = StudentNode.Descendants("Classroom").FirstOrDefault(arg => arg.Element("Name").Value == classroomName)
0 голосов
/ 10 августа 2011

Вы выбираете родительский узел узла Классная комната. Измените запрос следующим образом:

XElement classroom = StudentNode.Descendants("Classroom").First(arg => arg.Element("Name").Value == classroomName);

Вместо использования First вы должны использовать FirstOrDefault и проверить нулевое значение, чтобы остановить любые исключения, которые могут возникнуть, если не найдены узлы Classroom на основе вашего запроса. (Игнорируйте это, если вы обрабатываете это исключение в другом месте вашего кода)

Enumerable.FirstOrDefault

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...