Фильтрация и поиск данных XML

#c# #xml #linq #linq-to-xml

#c# #xml #linq #linq-to-xml

Вопрос:

У меня есть следующий фрагмент XML-кода, который я могу легко сгенерировать.

 <?xml version="1.0" encoding="utf-8"?>
<sessions>
  <session date="14.10.2016" time="0:1" amount="1">
    <Folder>C:Users</Folder>
    <Folder>C:Tes2t</Folder>
    <Folder>C:AsgbsfAleksei</Folder>
  </session>
  <session date="14.10.2016" time="15:40" amount="7">
    <Folder>C:Users</Folder>
    <Folder>C:Tes2taaaa</Folder>
    <Folder>C:AsgbsfAleksei</Folder>
  </session>
</sessions>
  

Я ищу данные с атрибутом time 15:40 и датой 14.10.2016, используя следующую функцию

 private static IEnumerable<XElement> FindElements(string filename, string date, string time)
{
    XElement x = XElement.Load(filename);

    return x.Descendants().Where(e => e.Attributes("date").Any(a => a.Value.Equals(date)) amp;amp;
    e.Attributes("time").Any(a => a.Value.Equals(time)));
}
  

Функция выполняется как:

 foreach (XElement x in FindElements(pathToXml, "14.10.2016", "15:40"))
    Console.WriteLine(x.ToString());
  

Все в порядке, но результат

 <session date="14.10.2016" time="15:40" amount="7">
    <Folder>C:Users</Folder>
    <Folder>C:Tes2taaaa</Folder>
    <Folder>C:AsgbsfAleksei</Folder>
</session>
  

И мне нужны только папки, например.

 <Folder>C:Users</Folder>
<Folder>C:Tes2taaaa</Folder>
<Folder>C:AsgbsfAleksei</Folder>
  

Как мне этого добиться? Помогите, пожалуйста.

Ответ №1:

(Кажется, я немного опоздал, но ..) в некоторых случаях, подобных этому, использовать Xpath проще, чем Linq .

 var folders = XDocument.Load(filename)
           .XPathSelectElements("//session[@dat‌​e='14.10.2016' and @time='15:40']/Folder");
  

Комментарии:

1. Согласен 🙂 об этом не подумал

Ответ №2:

В данный момент вы возвращаете, Element который имеет атрибут date и time с этими значениями. Что вам следует добавить к нему, так это вернуть его дочерние элементы Folder . Вы можете сделать это, добавив .Elements("Folder") после .Where .

Однако, я думаю, вы можете написать свой запрос немного лучше:

Найдите все session s, значения которых равны заданным входным данным. Затем верните element.Elements("Folder") .

Я добавил .SelectMany() для выравнивания внутреннего списка дочерних элементов

 string date = "14.10.2016";
string time = "15:40";

var result = (from element in XDocument.Load("data.xml").Descendants("session")
              where element.Attribute("date")?.Value == date amp;amp;
                    element.Attribute("time")?.Value == time
              select element.Elements("Folder")).SelectMany(item => item).ToList();
  

Комментарии:

1. Работает отлично. Большое вам спасибо, также спасибо за объяснение, это очень помогает!