1

I need to order the xmlelement by element name. Below i mentioned my before arrange and after arrange the file.

File datas like:

  <Root>
       <RB-3-10  K="3" P="0.5" L="5" G="5.5" E="3" l="5" O="2.5" />
       <RB-4-6   K="3" P="0.5" L="6" G="5.5" E="3" l="6" O="2.5" />
       <RB-3-5   K="3" P="0.5" L="10" G="5.5" E="3" l="10" O="2.5" />
       <RB-3-12  K="3" P="0.5" L="12" G="5.5" E="3" l="12" O="2.5" />
       <RB-4-14  K="3" P="0.5" L="14" G="5.5" E="3" l="14" O="2.5" />
       <RB-3-15  K="3" P="0.5" L="15" G="5.5" E="3" l="15" O="2.5" />
       <RB-5-16  K="3" P="0.5" L="16" G="5.5" E="3" l="16" O="2.5" />
  </Root>

But I need output like

  <Root>
       <RB-3-5    K="3" P="0.5" L="10" G="5.5" E="3" l="10" O="2.5" />
       <RB-3-10   K="3" P="0.5" L="5" G="5.5" E="3" l="5" O="2.5" />
       <RB-3-12   K="3" P="0.5" L="12" G="5.5" E="3" l="12" O="2.5" />
       <RB-3-15   K="3" P="0.5" L="15" G="5.5" E="3" l="15" O="2.5" />
       <RB-4-6    K="3" P="0.5" L="6" G="5.5" E="3" l="6" O="2.5" />
       <RB-4-14   K="3" P="0.5" L="14" G="5.5" E="3" l="14" O="2.5" />
       <RB-5-16   K="3" P="0.5" L="16" G="5.5" E="3" l="16" O="2.5" /> 
  </Root>

Any can know how to sort element by it's name.

Erik Philips
  • 53,428
  • 11
  • 128
  • 150
Sivaperuman
  • 239
  • 1
  • 4
  • 21

1 Answers1

7

Try this (assuming that you have the same pattern in the element names):

using System.Xml.Linq;

class Program
{
    static void Main(string[] args)
    {
        var xDoc = XDocument.Load("xml.xml");
        var ordered = xDoc.Root.Elements()
            .OrderBy(i => Convert.ToInt32(i.Name.LocalName.Split('-')[1]))
            .ThenBy(i => Convert.ToInt32(i.Name.LocalName.Split('-')[2]))
            .ToList();
        xDoc.Root.ReplaceAll(ordered);
        xDoc.Save("xml_1.xml");
    }
}

You could also use just one to OrderBy (without using ThenBy), but you have to know beforehand how large the integers could get in the XML tag names. Here's an example which assumes that there are no more than 2 digits.

var ordered = xDoc.Root.Elements()
    .OrderBy(i => Convert.ToInt32(
        i.Name.LocalName.Split('-')[1].PadLeft(2, '0') +
        i.Name.LocalName.Split('-')[2].PadLeft(2, '0')))
    .ToList();

Last but not least, here's a way to do it by using a IComparer implementation (credits should go to this answer):

var ordered = xDoc.Root.Elements()
    .OrderBy(i => i.Name.LocalName, new NaturalSortComparer())
    .ToList();

The NaturalSortComparer class:

public class NaturalSortComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        return StrCmpLogicalW(x, y);
    }

    [DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
    public static extern int StrCmpLogicalW(string x, string y);
}
Community
  • 1
  • 1
Alex Filipovici
  • 31,789
  • 6
  • 54
  • 78