http://www.cnblogs.com/gzcola/archive/2009/11/20/1607254.html
对xml数据排序的方法多种多样, 例如可以把xml数据转换为DataTable,然后进行排序;也可以使用xslt进行排序等等。
这里介绍如何使用XPathExpression 对xml数据根据某节点或者某一个attribute进行排序。
例如,我们根据PublishDate(发表时间) 节点对以下数据进行倒序排序:
Code
<? xml version="1.0" encoding="utf-8" ?> < Articles > < Article > < ID > 1 </ ID > < Title > Article1 </ Title > < PublishDate > 2009-06-05 08:45:25 </ PublishDate > </ Article > < Article > < ID > 2 </ ID > < Title > Article2 </ Title > < PublishDate > 2009-06-07 06:43:16 </ PublishDate > </ Article > < Article > < ID > 3 </ ID > < Title > Article3 </ Title > < PublishDate > 2009-11-05 01:01:40 </ PublishDate > </ Article > < Article > < ID > 4 </ ID > < Title > Article4 </ Title > < PublishDate > 2009-08-05 14:01:01 </ PublishDate > </ Article > < Article > < ID > 5 </ ID > < Title > Article5 </ Title > < PublishDate > 2009-12-05 09:25:34 </ PublishDate > </ Article > </ Articles >
Code
XmlDocument SortXMLDoc(XmlDocument xmldoc) { XmlDocument xmlDocCopy = new XmlDocument(); xmlDocCopy.LoadXml(xmldoc.OuterXml); XmlNode XmlNodeCopy = xmlDocCopy.SelectSingleNode( " //Articles " ); XmlNodeCopy.RemoveAll(); // XmlNodeCopy.InnerXml = "<NewsCategory Category=/"NA/"></NewsCategory>"; XmlNode node = xmldoc.SelectSingleNode( " //Articles " ); XPathNavigator navigator = node.CreateNavigator(); XPathExpression selectExpression = navigator.Compile( " Article/PublishDate " ); selectExpression.AddSort( " . " , XmlSortOrder.Descending, XmlCaseOrder.None, "" , XmlDataType.Text); // DateTimeComparer datesort = new DateTimeComparer(); // selectExpression.AddSort(".", datesort); XPathNodeIterator nodeIterator = navigator.Select(selectExpression); while (nodeIterator.MoveNext()) { // XmlNode currentNode = (XmlNode)nodeIterator.Current.ValueAs( typeof(XmlNode)) ; XmlNode linkNode = xmldoc.SelectSingleNode( " //Article[PublishDate=/ "" + nodeIterator.Current.Value + " / " ] " ); XmlNode importedLinkNode = xmlDocCopy.ImportNode(linkNode, true ); xmlDocCopy.SelectSingleNode( " //Articles " ).AppendChild(importedLinkNode); } return xmlDocCopy; }
留意selectExpression.AddSort(".", XmlSortOrder.Descending, XmlCaseOrder.None, "", XmlDataType.Text); 这句代码。
XmlDataType只支持Text 和 Number, 而我们需要排序的字段是DateTime类型,显然排序出来的数据肯定是不对的。
如何解决这个问题呢? 我们发现AddSort方法有重载,定义如下:
public abstract void AddSort(object expr, IComparer comparer);
我们可以实现自己的Comparer, 马上察看IComparer接口:
Code
namespace System.Collections { // Summary: // Exposes a method that compares two objects. [ComVisible( true )] public interface IComparer { // Summary: // Compares two objects and returns a value indicating whether one is less than, // equal to, or greater than the other. // // Parameters: // x: // The first object to compare. // // y: // The second object to compare. // // Returns: // Value Condition Less than zero x is less than y. Zero x equals y. Greater // than zero x is greater than y. // // Exceptions: // System.ArgumentException: // Neither x nor y implements the System.IComparable interface.-or- x and y // are of different types and neither one can handle comparisons with the other. int Compare( object x, object y); } }
我们只要实现Compare接口就可以了,代码如下:
Code
public class DateTimeComparer : IComparer { int IComparer.Compare(Object x, Object y) { return DateTime.Compare(Convert.ToDateTime(y), Convert.ToDateTime(x)); } }
然后把selectExpression.AddSort(".", XmlSortOrder.Descending, XmlCaseOrder.None, "", XmlDataType.Text);
代码替换成
DateTimeComparer datesort
=
new
DateTimeComparer(); selectExpression.AddSort(
"
.
"
, datesort);
就大功告成了!