如何在XElement属性上使用LINQ Group

时间:2013-12-27 10:03:28

标签: c# xml linq

var seriesonfo包含以下XML,

    <series id="S000002334Member">
      <class id="C000006118Member" />
    </series>
    <series id="S000002334Member">
      <class id="C000006119Member" />
    </series>

C#Code to group“series”节点基于“id”属性:

var result = new XElement("SC",
new[]
     {
       new XElement("seriesAndClassInfo", seriesonfo.GroupBy(a => a.Element("series").Attribute("id")))
     }

分组后的预期XML:

   <series id="S000002334Member">
      <class id="C000006118Member" />
      <class id="C000006119Member" />
    </series>

小组不工作。

2 个答案:

答案 0 :(得分:6)

基本上你需要按属性的(字符串)Value分组,而不是属性本身。

因为当您通过引用比较XAttribute时,即使它们具有相同的文本值,它们也会被视为不同。所以分组不起作用。

工作代码:

// (I added "root", otherwise the xml is invalid)
string original = "<root><series id=\"S000002334Member\"><class id=\"C000006118Member\" /></series><series id=\"S000002334Member\"><class id=\"C000006119Member\" /></series></root>";            
XElement originalXml = XElement.Parse(original);

var groups = originalXml              
    .Descendants("series")
    .GroupBy(a => a.Attribute("id").Value); // that's the important bit...

IEnumerable<XElement> afterGrouping = groups
    .Select(
        grp => // for each group...
            new XElement( // ...create a new element
                "series", 
                new XAttribute("id", grp.Key), 
                grp.Select(each => each.Element("class")))); // containing all "class" elements from the group

XElement final = new XElement("final", afterGrouping); // just adding root element again

// and the result is:
//
// <final>
//     <series id="S000002334Member">
//         <class id="C000006118Member" />
//         <class id="C000006119Member" />
//     </series>
// </final>

答案 1 :(得分:3)

var result = doc.Descendants("series").GroupBy(s => s.Attribute("id").Value)
            .Select(g => new XElement("series", new XAttribute("id", g.Key), 
                        g.SelectMany(c=>c.Descendants("class"))));