2013-08-22 3 views
1

XML:Как разбирать строку xml, используя linq для xml?

<shift_details> 
    <shift_time>10:00 to 10:30</shift_time> 
    <count>0</count> 
    <shift_time>10:30 to 11:00</shift_time> 
    <count>0</count> 
    <shift_time>11:00 to 11:30</shift_time> 
    <count>0</count> 
    <shift_time>11:30 to 12:00</shift_time> 
    <count>0</count> 
    <shift_time>12:00 to 12:30</shift_time> 
    <count>0</count> 
</shift_details> 

Код:

var slots = from c in xmlResponse.Descendants("shift_details") 
      select new TimeSlots 
      { 
       time = (string)c.Element("shift_time"), 
       count = (string)c.Element("count"), 
      }; 

выше код возврата только один слот элемент в качестве выходного .Но мой XML содержит слишком много записей.

Как читать все записи в приведенном выше xml?

+1

Я полагаю, вы имеете в виду linq для xml – Jonesopolis

+5

Если вы контролируете структуру XML, я бы изменил XML, потому что он не структурирован правильно –

ответ

5

Это потому, что Element возвращает только первый элемент с заданным именем. Вы должны рассмотреть вопрос об изменении своей структуры XML для разделения различных слотов друг от друга, например:

<shift_details> 
    <shift> 
     <shift_time>10:00 to 10:30</shift_time> 
     <count>0</count> 
    </shift> 
    (...) 
</shift_details> 

А затем запросить его так:

var slots = from c in xmlResponse.Element("shift_details").Elements("shift") 
      select new TimeSlots 
      { 
       time = (string)c.Element("shift_time"), 
       count = (string)c.Element("count"), 
      }; 

Или, если вы не можете изменить XML, вы может еще запросить, но это будет немного сложнее:

var doc = XDocument.Load("Input.txt"); 
var details = doc.Root; 

var times = details.Elements("shift_time"); 
var counts = details.Elements("count"); 

var slots = times.Zip(counts, (t, c) => new { time = (string)t, count = (string)c }).ToList(); 
+0

Приятное использование Zip (при условии, что XML всегда имеет такое же количество элементов shift_time и count. –

0

с другой стороны, если вы не можете изменить структуру XML, вам нужно, чтобы начать получать ting creative (хотя я не рекомендую его). В этом случае вы, вероятно, будет хорошо (даже если менее ремонтопригодны в долгосрочной перспективе) с чем-то вроде этого, который принимает коллекцию элементов и разбивает их на куски каждый из которых содержит уникальные элементы:

public static class Extensions 
{ 
    public static IEnumerable<IEnumerable<XElement>> Partition(this IEnumerable<XElement> elements) 
    { 
     var currentList = new List<XElement>(); 
     var tags = new HashSet<string>(); 

     foreach (var xElement in elements) 
     { 
      if (tags.Contains(xElement.Name.LocalName)) 
      { 
       yield return currentList.ToArray(); 
       currentList.Clear(); 
       tags.Clear(); 
      } 

      currentList.Add(xElement); 
      tags.Add(xElement.Name.LocalName); 
     } 

     yield return currentList.ToArray(); 
    } 
} 

Вы можете затем запустите коллекцию детей под переменными shift_details и получите достаточно простые для обработки группы. Должно быть прямолинейным отсюда.