2014-10-26 40 views
0
<root> 
    <level1 name="A"> 
     <level2 name="A1" /> 
     <level2 name="A2" /> 
    </level1> 
    <level1 name="B"> 
     <level2 name="B1" /> 
     <level2 name="B2" /> 
    </level1> 
    <level1 name="C" /> 
</root> 

可能有人給我使用LINQ,最簡單的方法來打印這個結果的C#代碼: (注意額外的空間,如果它是一個level2的節點)LINQ和XML與C#

A 
    A1 
    A2 
B 
    B1 
    B2 
C 

XDocument xdoc = XDocument.Load("data.xml")); 
var lv1s = from lv1 in xdoc.Descendants("level1") 
      select lv1.Attribute("name").Value; 

foreach (var lv1 in lv1s) 
{ 
    result.AppendLine(lv1); 

    var lv2s = from lv2 in xdoc...??? 
} 
+1

-1您完全改變了您的問題,使所有答案無效。 – EZI 2014-10-30 16:44:14

回答

3
var xDoc = XDocument.Load(filename); 
var lookup = xDoc.Descendants("param") 
       .ToLookup(x => x.Attribute("name").Value, x => (double)x); 

foreach (var p in lookup) 
{ 
    Console.WriteLine("{0,-12} {1,6:#0.0} {2,6:#0.0} {3,6:#0.0}", 
         p.Key, p.Min(), p.Average(), p.Max()); 
} 

OUTPUT:

temperature  9.3 10.3 11.2 
pH    3.0 6.3 10.0 
Phosphate  4.0 4.0 4.0 
Chloride  4.0 4.0 4.0 
Nitrate  10.0 10.0 10.0 
0

通過使用XPath,這裏是你怎麼可能對於一般做:

float GetAvgTemperature(XmlDocument document) 
{ 
    var temperatureNodes = document.SelectNodes("/samples/measurement/param[@name='temperature']"); 
    return temperatureNodes == null ? 0 : temperatureNodes.Cast<XmlNode>().Average(node => float.Parse(node.InnerText, CultureInfo.InvariantCulture)); 
} 

您可以輕鬆使此函數更通用,以返回Minimum/Average/Maximum和任何參數名稱。

+0

他使用'XDocument',而不是'XmlDocument'。 – 2014-10-26 20:42:28

+0

@CoryNelson它是如此重要嗎?只有方法名稱更改'XPathSelectElements' – EZI 2014-10-26 21:39:44

+0

沒有意識到這一點,但我認爲OP沒有具體提到該解決方案必須使用'XDocument',並且正如EZI所建議的那樣,它並沒有太大區別。與其他答案的真正區別在於我的解決方案使用xPath引擎,它有其優點和缺點。 – 2014-10-26 22:29:24

0

該方法使用LINQ聚合按照您的要求在單行代碼中構建計算。

var values = samples.Descendants(XName.Get("param")) 
    .Select(n => new { 
     Name = n.Attribute(XName.Get("name")).Value, 
     Value = float.Parse(n.Value) 
    }) 
    .GroupBy(a => a.Name) 
    .Select(a => new { 
     Name = a.Key, 
     MaxValue = a.Max(g => g.Value), 
     MinValue = a.Min(g => g.Value), 
     AvgValue = a.Average(g => g.Value) 
    }) 
    .ToArray(); 
0

我會避免使用Descendants("param"),除非您以另一種方式驗證文檔。否則,如果文檔格式發生變化,可能會導致一些意外的結果。

這裏有你想要的東西:

from p in samples.Elements("samples").Elements("measurement").Elements("param") 
group (double)p by (string)p.Attribute("name") into grp 
select new 
{ 
    ParameterName = grp.Key, 
    Min = grp.Min(), 
    Avg = grp.Average(), 
    Max = grp.Max() 
} 

注意鏈的Elements()通話,這使得精確選擇下入文檔很瑣碎,而且XAttributeXElement直接doublestring鑄造得到他們的價值觀。