views:

1351

answers:

5

I want to change the order of XML using XDocument

<root>
  <one>1</one>
  <two>2</two>
</root>

I want to change the order so that 2 appears before 1. Is this capability baked in or do I have to do it myself. For example, remove then AddBeforeSelf()?

Thanks

A: 

This should do the trick. It order the child nodes of the root based on their content and then changes their order in the document. This is likely not the most effective way but judging by your tags you wanted to see it with LINQ.

static void Main(string[] args)
{
    XDocument doc = new XDocument(
        new XElement("root",
            new XElement("one", 1),
            new XElement("two", 2)
            ));

    var results = from XElement el in doc.Element("root").Descendants()
                  orderby el.Value descending
                  select el;

    foreach (var item in results)
        Console.WriteLine(item);

    doc.Root.ReplaceAll( results.ToArray());

    Console.WriteLine(doc);

    Console.ReadKey();
}
smaclell
A: 

That works for sorting, but I just want them rearranged. For example, push one up in order. I think what I'll do is either ElementsAfterSelf or ElementsBeforeSelf then select the last or first node. Then Remove what I want to move, then use the selected node and use AddBeforeSelf or AddAfterSelf.

I don't see anything baked in that will do this.

B2
+1  A: 

Outside of writing C# code to achieve this, you could use XSLT to transform the XML.

Jeff Yates
+1  A: 

Hi,

Similar to above, but wrapping it in an extension method. In my case this works fine for me as I just want to ensure a certain element order is applied in my document before the user saves the xml.

public static class XElementExtensions
{
    public static void OrderElements(this XElement parent, params string[] orderedLocalNames)
    {            
        List<string> order = new List<string>(orderedLocalNames);            
        var orderedNodes = parent.Elements().OrderBy(e => order.IndexOf(e.Name.LocalName) >= 0? order.IndexOf(e.Name.LocalName): Int32.MaxValue);
        parent.ReplaceNodes(orderedNodes);
    }
}
// using the extension method before persisting xml
this.Root.Element("parentNode").OrderElements("one", "two", "three", "four");
A: 

Try this solution...

XElement node = ...get the element...

//Move up
if (node.PreviousNode != null) {
    node.PreviousNode.AddBeforeSelf(node);
    node.Remove();
}

//Move down
if (node.NextNode != null) {
    node.NextNode.AddAfterSelf(node);
    node.Remove();
}
podeig