0

The code looks like this:

<xx>
    <xy>
        <xz>
            <xx somestring="bbb" value= "0"...>
            <xx somestring="cad" value= "0"...>
            <xx somestring="axa" value= "0"...>
            <xx somestring="aaa" value= "0"...>
        <xz>
    <xy>
<xx>

This needs to be sorted by "somestring" alphabetical, the dept of the nodes is variable and the name of xx, xy, xz are also variable, the only thing that is always there is "somestring" which needs to be sorted in that way, but the order of the parents needs to keep the same. Just

Anyone able to help me out here? Would be awesome if done in LINQ.

Thanks in advance

ChekaZ
  • 9
  • 5
  • http://stackoverflow.com/questions/18464737/c-sort-xml-node-using-attribute-value , but please keep in mind, this "sort" only works in a ascii way, as soon as you serialize stuff, the order could become different again. If you really need ordering, you should consider adding an xml element like "order=1...n" – Najzero Sep 21 '16 at 12:57
  • I saw that thread, but it doesnt fit my needs. Is there no way to sort all childs with this specific value (dynamic) ? – ChekaZ Sep 21 '16 at 13:09
  • as I see it, it should perfectly fit, but instead of `.OrderByDescending(s => (int) s.Attribute("aa")); ` you would need to `.OrderByAscending(s => s.Attribute("somestring"));` ( missing int cast ) – Najzero Sep 21 '16 at 13:13
  • Already tried this, maybe Ive done something wrong. Hes able to call the Parent names to get to that value, but mine are variable. Hes calling xDoc.Element("Root") .Elements("I") – ChekaZ Sep 21 '16 at 13:18

1 Answers1

0

Here is an example that sorts independent of the name of elements, simply by the value you select based on a Func<XElement, TKey>:

class Program
{
    static void Main(string[] args)
    {
        XDocument doc = XDocument.Load("../../XMLFile1.xml");
        doc.Root.Sort(el => (string)el.Attribute("bar"));
        doc.Save(Console.Out);
    }

}

public static class MyExt
{
    public static void Sort<TKey>(this XElement input, Func<XElement, TKey> selector)
    {
        input.Elements().ToList().ForEach(el => el.Sort(selector));
        input.ReplaceNodes(input.Elements().OrderBy(selector));
    }
}

With an input of

<?xml version="1.0" encoding="utf-8" ?>
<root>
  <section>
    <foo bar="az">
      <baz bar="c"/>
      <baz bar="b"/>
      <baz bar="a"/>
    </foo>
    <foo bar="am"/>
  </section>
  <section>
    <div>
      <value bar="x"/>
      <value bar="d"/>
      <value bar="a"/>
    </div>
  </section>
</root>

the output is

<root>
  <section>
    <foo bar="am" />
    <foo bar="az">
      <baz bar="a" />
      <baz bar="b" />
      <baz bar="c" />
    </foo>
  </section>
  <section>
    <div>
      <value bar="a" />
      <value bar="d" />
      <value bar="x" />
    </div>
  </section>
</root>

So for your sample you would use doc.Root.Sort(el => (string)el.Attribute("somestring"));.

Martin Honnen
  • 160,499
  • 6
  • 90
  • 110