2013-08-22 74 views
1

XML:如何使用linq to xml解析下面的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的結構,你需要開始獲取(雖然我不推薦它)。在這種情況下,你可能會確定(即使從長遠來看,少維護)有這樣的事情,這需要元素的集合,並將其分成塊的每個含有獨特的元素:

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下運行收集的孩子,並獲得相當容易的處理組。應該從這裏直接前進。