Как я могу отсортировать записи XML с помощью LibXML и Perl?

Я анализирую XML-файл с помощью LibXML и мне нужно отсортировать записи по дате. Каждая запись имеет два поля даты, одно для того, когда запись была опубликована, и одно, когда она была обновлена.

<?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 сортировать хеш, который сейчас работает отлично.

2 ответа

Решение

Одним из способов будет изменить ваш 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') ) {
    ...
}

Надеюсь это немного поможет!

Чистая сортировка может привести к смещению времен из разных часовых поясов:

 print for sort "2009-06-15T08:00:00+07:00", "2009-06-15T04:00:00+00:00";

Здесь второй раз через 3 часа после первого, но сортирует первый.

Я не уверен, что вы подразумеваете под "вонючий". Ваш пример просто показывает временные метки в формате rfc3339.

Другие вопросы по тегам