3

LibXMLを使用して XML ファイルを解析していて、エントリを日付順に並べ替える必要があります。各エントリには 2 つの日付フィールドがあり、1 つはエントリが公開された日付、もう 1 つは更新された日付です。

<?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 を解析し、必要な値をハッシュに格納する関数を作成しました。次に、baresortを使用してハッシュを並べ替えましたが、現在は問題なく機能しています。

4

2 に答える 2

5

reverse1つの方法は、あなたを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') ) {
    ...
}

これが少し役立つことを願っています!

于 2009-06-13T12:34:39.040 に答える
2

単純な並べ替えでは、異なるタイムゾーンの時間が順不同になる場合があります。

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

ここでは、2 回目は 1 回目から 3 時間後ですが、最初にソートされます。

あなたが言っている「ワキガ」の意味がわかりません。あなたの例は、タイムスタンプをrfc3339形式で表示するだけです。

于 2009-06-14T19:37:36.707 に答える