1

I am trying to sort XML using Linq but its not working Here is the XML

<hierarchy>
  <date>2015/04/01 15:29:10</date>
  <folder name="Root" id="Root">
    <file id="Fukui_R3_20150327182224.xlsx" />
    <file id="BordersTest_20150330144902.xlsx" />
    <folder name="level-1" id="1427455995512">
      <file id="Fukui_R3_20150327182224.xlsx" />
      <file id="BordersTest_20150330144902.xlsx" />
      <folder name="Zxcf" id="1427869724768">
        <file id="Fukui_R3_20150327182224.xlsx" />
        <file id="BordersTest_20150330144902.xlsx" />
      </folder>
      <folder name="Aegh" id="1427869732372">
        <file id="Fukui_R3_20150327182224.xlsx" />
        <file id="BordersTest_20150330144902.xlsx" />
      </folder>
      <folder name="Cfgt" id="1427869741718" />
    </folder>
    <folder name="A-level" id="1427869672074" />
    <folder name="G-Level" id="1427869682304" />
    <folder name="E-Level" id="1427869690384" />
    <folder name="1-A-Level" id="1427869701383" />
  </folder>
</hierarchy>

and here is the code I have tried

 XDocument xDoc = XDocument.Load(FilePath);
 foreach (var trans in xDoc.Descendants("hierarchy"))
 {
     trans.ReplaceAll( trans.Elements().OrderBy(x=>x.Name.LocalName));
 }

 string newXml = xDoc.ToString();

but it return me same unsorted XML.

7
  • are you saving the xdoc after changing it? Commented Apr 1, 2015 at 6:34
  • no I haven't saved it yet just seeing result as string Commented Apr 1, 2015 at 6:35
  • 2
    Aren't the sub-elements of "hierarchy" already ordered by local name? Their order is "date", then "folder". Commented Apr 1, 2015 at 6:38
  • I think the flow should be you take your data in xdoc alter it then again load into the same and save it. this is how it should be.... Commented Apr 1, 2015 at 6:40
  • 2
    Just to be clear, the Name.LocalName of <folder name="Root" id="Root"> is "folder". Perhaps you want to sort on an attribute named "name"? Commented Apr 1, 2015 at 6:42

1 Answer 1

3

Rewrite your code like this:

XDocument xDoc = XDocument.Load(FilePath);
if (xDoc.Root != null)
    SortXml(xDoc.Root);
string newXml = xDoc.ToString();

and try to use this method:

private static void SortXml(XContainer parent)
{
    var elements = parent.Elements()
        .OrderByDescending(e => e.Name.LocalName)
        .ThenBy(e => (string)e.Attribute("name"))
        .ToArray();

    Array.ForEach(elements, e => e.Remove());

    foreach (var element in elements) {
        parent.Add(element);
        SortXml(element);
    }
}

This code recursively sort your hierarchy: files always goes after folders and all items are sorted by value of attribute "name".

Sign up to request clarification or add additional context in comments.

3 Comments

Yes it worked but one issue the string this method returns there is no value in date.
@AdilWaqar, try this: var sortednodes = xDoc.Root.Elements().OrderByDescending(e => e.Name.LocalName) .ThenBy(e => (string)e.Attribute("name"));
Adil, you right, removeNodes removes ALL nodes, including child elements, text nodes and so on. I replaced this by Array.ForEach(elements, e => e.Remove()); Now it's work fine.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.