假设我生成的XmlDocument具有如下所示的InnerXml:
<ORM_O01> <MSH> <MSH.9> <MSG.2>O01</MSG.2> </MSH.9> <MSH.6> <HD.1>13702</HD.1> </MSH.6> </MSH> <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> </ORM_O01>
如您所见,节点< PID.18>在节点< PID.3>之前. (< MSH.9>也在< MSH.6>之前).
重构我的一代将导致我干净的代码变得非常混乱.
有没有办法对节点进行排序,以便它排序alpha直到它到达最后一个句点然后排序数字(如果最后的值是数字)?
通过“数字排序”我的意思是它将查看整数而不是char的char. (所以18> 3).
解决方法
显而易见的答案是肯定的.
如果这是您想要的结果:
<ORM_O01> <MSH> <MSH.6> <HD.1>13702</HD.1> </MSH.6> <MSH.9> <MSG.2>O01</MSG.2> </MSH.9> </MSH> <ORM_O01.PATIENT> <PID> <PID.3> <CX.1>108</CX.1> </PID.3> <PID.18> <CX.1>SecondTestFin</CX.1> </PID.18> </PID> </ORM_O01.PATIENT> </ORM_O01>
那么这堂课就会这样做:(我应该为此付出代价…)
using System; using System.IO; using System.Linq; using System.Xml.Linq; namespace Test { public class SortXmlFile { XElement rootNode; public SortXmlFile(FileInfo file) { if (file.Exists) rootNode = XElement.Load(file.FullName); else throw new FileNotFoundException(file.FullName); } public XElement SortFile() { SortElements(rootNode); return rootNode; } public void SortElements(XElement root) { bool sortWithNumeric = false; XElement[] children = root.Elements().ToArray(); foreach (XElement child in children) { string name; int value; // does any child need to be sorted by numeric? if (!sortWithNumeric && Sortable(child,out name,out value)) sortWithNumeric = true; child.Remove(); // we'll re-add it in the sort portion // sorting child's children SortElements(child); } // re-add children after sorting // sort by name portion,which is either the full name,// or name that proceeds period that has a numeric value after the period. IOrderedEnumerable<XElement> childrenSortedByName = children .OrderBy(child => { string name; int value; Sortable(child,out value); return name; }); XElement[] sortedChildren; // if needed to sort numerically if (sortWithNumeric) { sortedChildren = childrenSortedByName .ThenBy(child => { string name; int value; Sortable(child,out value); return value; }) .ToArray(); } else sortedChildren = childrenSortedByName.ToArray(); // re-add the sorted children foreach (XElement child in sortedChildren) root.Add(child); } public bool Sortable(XElement node,out string name,out int value) { var dot = new char[] { '.' }; name = node.Name.ToString(); if (name.Contains(".")) { string[] parts = name.Split(dot); if (Int32.TryParse(parts[1],out value)) { name = parts[0]; return true; } } value = -1; return false; } } }
有人可能会写出这种更清洁和更清洁的东西,但这应该会让你前进.