Вас заинтересовал ваш вопрос, так вот мои два цента.
Я реализовал IComparer<T>
для обработки сравнений элементов и двух методов, которые обрабатывают рекурсию. Код можно немного почистить, но я вставил в код консольного приложения, которое я создал, чтобы показать вам мое решение, которое, я думаю, сработало.
Редактировать: Чтобы облегчить чтение, я разбил его на основные части, хотя и оставил приложение для функциональной консоли
IComparer<T>
Реализация:
public class SplitComparer : IComparer<string>
{
public int Compare(string x, string y)
{
var partsOfX = x.Split('.');
int firstNumber;
if (partsOfX.Length > 1 && int.TryParse(partsOfX[1], out firstNumber))
{
var secondNumber = Convert.ToInt32(y.Split('.')[1]);
return firstNumber.CompareTo(secondNumber);
}
return x.CompareTo(y);
}
}
Методы обработки рекурсии:
private static XElement Sort(XElement element)
{
var xe = new XElement(element.Name, element.Elements().OrderBy(x => x.Name.ToString(), new SplitComparer()).Select(x => Sort(x)));
if (!xe.HasElements)
{
xe.Value = element.Value;
}
return xe;
}
private static XDocument Sort(XDocument file)
{
return new XDocument(Sort(file.Root));
}
Функциональное консольное приложение:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Xml.Linq;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var xml = @"<ORM_O01>
<ORM_O01.PATIENT>
<PID>
<PID.18>
<CX.1>SecondTestFin</CX.1>
</PID.18>
<PID.3>
<CX.1>108</CX.1>
</PID.3>
</PID>
</ORM_O01.PATIENT>
<MSH>
<MSH.9>
<MSG.2>O01</MSG.2>
</MSH.9>
<MSH.6>
<HD.1>13702</HD.1>
</MSH.6>
</MSH>
</ORM_O01>";
var xDoc = XDocument.Parse(xml);
var result = Sort(xDoc);
Console.WriteLine(result.ToString());
Console.Read();
}
private static XElement Sort(XElement element)
{
var xe = new XElement(element.Name, element.Elements().OrderBy(x => x.Name.ToString(), new SplitComparer()).Select(x => Sort(x)));
if (!xe.HasElements)
{
xe.Value = element.Value;
}
return xe;
}
private static XDocument Sort(XDocument file)
{
return new XDocument(Sort(file.Root));
}
}
public class SplitComparer : IComparer<string>
{
public int Compare(string x, string y)
{
var partsOfX = x.Split('.');
int firstNumber;
if (partsOfX.Length > 1 && int.TryParse(partsOfX[1], out firstNumber))
{
var secondNumber = Convert.ToInt32(y.Split('.')[1]);
return firstNumber.CompareTo(secondNumber);
}
return x.CompareTo(y);
}
}
}