测试资料:
<Config> <Item a='1' b='5' c='9' m='9'/> <Item a='2' b='6' c='9' m='9'/> <Item a='3' b='7' c='9' m='9'/> <Item a='4' b='8' c='9' m='1'/> <Item a='5' b='9' c='9' m='1'/> <Item a='6' b='0' c='5' m='1'/> <Item a='7' b='1' c='5' m='1'/> <Item a='8' b='2' c='5' m='5'/> <Item a='9' b='3' c='5' m='5'/> <Item a='0' b='4' c='5' m='5'/> <Item a='A' b='5' c='5' m='5'/> </Config>
测试结果:
1. 依 c 及 b 属性排序
2. b 属性改由大到小排序
c,b a=6 b=0 c=5 m=1 a=7 b=1 c=5 m=1 a=8 b=2 c=5 m=5 a=9 b=3 c=5 m=5 a=0 b=4 c=5 m=5 a=A b=5 c=5 m=5 a=1 b=5 c=9 m=9 a=2 b=6 c=9 m=9 a=3 b=7 c=9 m=9 a=4 b=8 c=9 m=1 a=5 b=9 c=9 m=1 c,-b a=A b=5 c=5 m=5 a=0 b=4 c=5 m=5 a=9 b=3 c=5 m=5 a=8 b=2 c=5 m=5 a=7 b=1 c=5 m=1 a=6 b=0 c=5 m=1 a=5 b=9 c=9 m=1 a=4 b=8 c=9 m=1 a=3 b=7 c=9 m=9 a=2 b=6 c=9 m=9 a=1 b=5 c=9 m=9
测试程序:
static void Main(string[] args) { var xml = new XmlDocument(); xml.LoadXml(@"<Config> <Item a='1' b='5' c='9' m='9'/> <Item a='2' b='6' c='9' m='9'/> <Item a='3' b='7' c='9' m='9'/> <Item a='4' b='8' c='9' m='1'/> <Item a='5' b='9' c='9' m='1'/> <Item a='6' b='0' c='5' m='1'/> <Item a='7' b='1' c='5' m='1'/> <Item a='8' b='2' c='5' m='5'/> <Item a='9' b='3' c='5' m='5'/> <Item a='0' b='4' c='5' m='5'/> <Item a='A' b='5' c='5' m='5'/> </Config>"); var keepRunning = true; while (keepRunning) { var command = Console.ReadLine(); switch (command) { case "/exit": case "/quit": keepRunning = false; break; default: try { foreach (var i in xml.SelectNodes("/Config/Item", command)) { foreach (XmlAttribute a in i.Attributes) Console.Write("{0}={1} ", a.Name, a.Value); Console.WriteLine(); } } catch (Exception ex) { Console.WriteLine(ex.Message); } break; } } }
核心程序:
public static class XmlSorter { public static IEnumerable<XmlNode> SelectNodes(this XmlNode node, string xpath, string orderby) { var sorter = Sorter.Create(orderby); return sorter == null ? node.SelectNodes(xpath).AsEnumerable() : sorter.Sort(node.SelectNodes(xpath)); } private static IEnumerable<XmlNode> AsEnumerable(this XmlNodeList list) { foreach (XmlNode i in list) yield return i; } private static string Attrib(this XmlNode node, string name, string defaultValue) { return (node.Attributes[name] == null) ? defaultValue : node.Attributes[name].Value; } class Sorter { public string Key { get; set; } public bool Descending { get; set; } public Sorter Next { get; set; } private IOrderedEnumerable<XmlNode> Sort(IOrderedEnumerable<XmlNode> list) { var flow = (Next != null ? 0x10 : 0x00) + (Descending ? 0x01 : 0x00); switch (flow) { case 0x11: return Next.Sort(list.ThenByDescending(o => o.Attrib(Key, ""))); case 0x10: return Next.Sort(list.ThenBy(o => o.Attrib(Key, ""))); case 0x01: return list.ThenByDescending(o => o.Attrib(Key, "")); case 0x00: return list.ThenBy(o => o.Attrib(Key, "")); } throw new Exception("!!!"); } public IEnumerable<XmlNode> Sort(XmlNodeList nodes) { var flow = (Next != null ? 0x10 : 0x00) + (Descending ? 0x01 : 0x00); switch (flow) { case 0x11: return Next.Sort(nodes.AsEnumerable().OrderByDescending(o => o.Attrib(Key, ""))); case 0x10: return Next.Sort(nodes.AsEnumerable().OrderBy(o => o.Attrib(Key, ""))); case 0x01: return nodes.AsEnumerable().OrderByDescending(o => o.Attrib(Key, "")); case 0x00: return nodes.AsEnumerable().OrderBy(o => o.Attrib(Key, "")); } return null; } public static Sorter Create(string orderby) { if (string.IsNullOrEmpty(orderby)) return null; var fields = orderby.Split(','); var list = new List<Sorter>(); foreach (var i in fields) { var s = i.Trim(); var desc = s.StartsWith("-"); var key = desc ? s.Substring(1) : s; if (string.IsNullOrEmpty(key)) continue; list.Add(new Sorter { Key = key, Descending = desc }); } for (int i = 1; i < list.Count; i++) list[i - 1].Next = list[i]; if (list.Count > 0) return list[0]; return null; } } }
原谅链接:http://www.dotblogs.com.tw/cihsieh/archive/2013/11/26/131445.aspx