Reputation: 83
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
Upvotes: 8
Views: 8398
Reputation: 2741
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();
}
Upvotes: 3
Reputation:
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");
Upvotes: 6
Reputation: 62357
Outside of writing C# code to achieve this, you could use XSLT to transform the XML.
Upvotes: 1
Reputation: 4658
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();
}
Upvotes: 1