Vac*_*ano 6 .net c# xml xmldocument .net-4.0
假设我有一个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>
Run Code Online (Sandbox Code Playgroud)
如您所见,节点<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>
Run Code Online (Sandbox Code Playgroud)
然后这个类就会这样做:(我应该为此得到报酬......)
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 name, out value);
return name;
});
XElement[] sortedChildren;
// if needed to sort numerically
if (sortWithNumeric)
{
sortedChildren = childrenSortedByName
.ThenBy(child =>
{
string name;
int value;
Sortable(child, out name, 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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
也许有人可以写得更干净、更简洁,但这应该能让你继续下去。