我正在使用LibXML解析XML文件,需要按日期对条目进行排序。每个条目都有两个日期字段,一个用于发布条目,另一个用于更新条目。
<?xml version="1.0" encoding="utf-8"?>
...
<entry>
<published>2009-04-10T18:51:04.696+02:00</published>
<updated>2009-05-30T14:48:27.853+03:00</updated>
<title>The title</title>
<content>The content goes here</content>
</entry>
...
XML文件已按更新日期排序,最新的第一个。我可以轻松地将其反转为将旧条目放在第一位:
my $parser = XML::LibXML->new();
my $doc = $parser->parse_file($file);
my $xc = XML::LibXML::XPathContext->new($doc->documentElement());
foreach my $entry (reverse($xc->findnodes('//entry'))) {
...
}
但是,我需要按发布日期对文件进行反向排序,而不是按日期更新。我怎样才能做到这一点?时间戳看起来有点不稳定。我需要先将其标准化吗?
谢谢!
更新:
在摆弄XPath命名空间并失败之后,我创建了一个解析XML并在哈希中存储我需要的值的函数。然后我使用一个裸sort
来对哈希进行排序,现在效果很好。
答案 0 :(得分:5)
一种方法是将您的reverse
更改为sort
声明(未经测试):
sub parse_date {
# Transforms date from 2009-04-10T18:51:04.696+02:00 to 20090410
my $date= shift;
$date= join "", $date =~ m!\A(\d{4})-(\d{2})-(\d{2}).*!;
return $date;
}
sub by_published_date {
my $a_published= parse_date( $a->getChildrenByTagName('published') );
my $b_published= parse_date( $b->getChildrenByTagName('published') );
# putting $b_published in front will ensure the descending order.
return $b_published <=> $a_published;
}
foreach my $entry ( sort by_published_date $xc->findnodes('//entry') ) {
...
}
希望这有点帮助!
答案 1 :(得分:2)
裸排序可能会使不同时区的时间乱序:
print for sort "2009-06-15T08:00:00+07:00", "2009-06-15T04:00:00+00:00";
此处,第二次是在第一次之后3小时,但先排序。
我不确定你是什么意思“wonky”。您的示例只显示rfc3339格式的时间戳。