So recently I was dealing with an internal program that was easily confused and would create XML files with the elements in the wrong order for the schemas used in other internal programs that read these Xml files. I started looking for a fast way to reorder these elements and found this forum post which while on the right track was a bit more complicated than I really needed. So I came up with this solution.
<data name="ConfigName"> <One>Item One</One> <Three> <A>Item A</A> <C>Item C</C> <C>Item C-2</C> <B>Item B</B> </Three> <Two>Item Two</Two> </data>
<data name="ConfigName"> <One>Item One</One> <Two>Item Two</Two> <Three> <A>Item A</A> <B>Item B</B> <C>Item C</C> <C>Item C-2</C> </Three> </data>
Reorder Solution
string[] rootOrder = new string[] { "One", "Two", "Three" }; string[] threeOrder = new string[] { "A", "B", "C" }; XDocument xdoc = XDocument.Load("file.xml"); Reorder(xdoc, rootOrder); Reorder(xdoc.Root.Elements("Three"), threeOrder); void Reorder(XDocument xdoc, params string[] order) { xdoc.Root.ReplaceWith(Reorder(xdoc.Root, order)); } void Reorder(IEnumerable<XElement> els, params string[] order) { foreach (XElement el in els.ToArray()) el.ReplaceWith(Reorder(el, order)); } XElement Reorder(XElement root, params string[] order) { return new XElement(root.Name, from el in order select root.Elements(el), root.Attributes()); }
For those needing VB.NET
Module Module1
Sub Main() Dim rootOrder() As String = {"One", "Two", "Three"} Dim threeOrder() As String = {"A", "B", "C"}
Dim xdoc As XDocument = XDocument.Load("file.xml")
Reorder(xdoc, rootOrder) Reorder(xdoc.Root.Elements("Three"), threeOrder)
xdoc.Save("good.xml") End Sub
Private Sub Reorder(ByVal xdoc As XDocument, ByVal ParamArray order() As String) xdoc.Root.ReplaceWith(Reorder(xdoc.Root, order)) End Sub
Private Sub Reorder(ByVal els As IEnumerable(Of XElement), ByVal ParamArray order() As String) For Each el As XElement In els.ToArray() el.ReplaceWith(Reorder(el, order)) Next End Sub
Private Function Reorder(ByVal root As XElement, ByVal order As String()) As XElement Return New XElement(root.Name, (From el In order Let x As IEnumerable(Of XElement) = root.Elements(el) Select x), root.Attributes()) End FunctionEnd Module