对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);
就大功告成了!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?