我有一个XML文档,其中包含一些日期数据,例如:
<Message>
<messagetext>Testing purpose only</messagetext>
<date>05.02.2010</date>
</Message>
我希望按照XPath键对它们进行排序,我应该如何做到呢?
我有一个XML文档,其中包含一些日期数据,例如:
<Message>
<messagetext>Testing purpose only</messagetext>
<date>05.02.2010</date>
</Message>
XPathDocument doc = new XPathDocument(@"..\..\XMLFile1.xml");
XPathNavigator nav = doc.CreateNavigator();
XPathExpression exp = nav.Compile("Messages/Message");
exp.AddSort(
"number(concat(substring(date, 7), substring(date, 4, 2), substring(date, 1, 2)))",
XmlSortOrder.Descending,
XmlCaseOrder.None,
null,
XmlDataType.Number
);
foreach (XPathNavigator msg in nav.Select(exp))
{
Console.WriteLine(
"{0}: {1}",
msg.SelectSingleNode("date").Value,
msg.SelectSingleNode("messagetext").Value
);
}
将XMLFile1.xml作为
<Messages>
<Message>
<messagetext>Message 2</messagetext>
<date>04.02.2010</date>
</Message>
<Message>
<messagetext>Message 1</messagetext>
<date>05.02.2010</date>
</Message>
<Message>
<messagetext>Message 3</messagetext>
<date>05.02.2009</date>
</Message>
</Messages>
05.02.2010: Message 1
04.02.2010: Message 2
05.02.2009: Message 3
假定的日期格式是ddmmyyyy,但如果你想要mmddyyyy,你可以根据需要更改这些子字符串表达式。
using System;
using System.Linq;
using System.Xml.Linq;
public class Message
{
public string Text { get; set; }
public DateTime Date { get; set; }
}
class Program
{
static void Main(string[] args)
{
XDocument doc = XDocument.Load("input.xml");
var messages = doc.Descendants("Message")
.Select(element => new Message
{
Text = element.Element("messagetext").Value,
Date = DateTime.ParseExact(element.Element("date").Value, "MM.dd.yyyy", null)
}).OrderBy(message => message.Date);
foreach (Message message in messages)
{
Console.WriteLine("{0} : {1}", message.Date, message.Text);
}
}
}
结果:
02-05-2010 00:00:00 : Test1
17-05-2010 00:00:00 : Test2
22-05-2010 00:00:00 : Test3
我使用的测试数据:
<xml>
<Message>
<messagetext>Test1</messagetext>
<date>05.02.2010</date>
</Message>
<Message>
<messagetext>Test3</messagetext>
<date>05.22.2010</date>
</Message>
<Message>
<messagetext>Test2</messagetext>
<date>05.17.2010</date>
</Message>
</xml>
Func<XElement, DateTime> fn = e => DateTime.ParseExact(e.Element("date").Value, "dd.MM.yyyy", CultureInfo.InvariantCulture);
var messages = doc.Root.Elements("Message").OrderBy(fn);
foreach (var elem in messages)
{
Console.WriteLine(fn(elem));
}
另外,如果您有理由坚持使用XmlDocument,则这段代码略显臃肿但依然可用:
Func<XmlElement, DateTime> fn = e => DateTime.ParseExact(e.SelectSingleNode("date").InnerText, "dd.MM.yyyy", CultureInfo.InvariantCulture);
var messages = doc.DocumentElement.SelectNodes("Message")
.Cast<XmlElement>().OrderBy(fn);
foreach (var elem in messages)
{
Console.WriteLine(fn(elem));
}