2009-06-13 69 views
3

我使用LibXML解析XML文件,並需要按日期對條目進行排序。每個條目都有兩個日期字段,一個用於發佈條目,另一個用於更新時間。如何使用LibXML和Perl對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'))) { 
    ... 
} 

不過,我需要逆向排序按日期公佈的文件,而不是按日期進行更新。我怎樣才能做到這一點?時間戳也看起來有點won。。我需要首先對其進行標準化嗎?

謝謝!

更新: 在擺弄XPath命名空間和失敗之後,我做了一個函數,它解析XML並將所需的值存儲在一個哈希中。然後,我用一個光禿禿的sort對散列進行排序,現在工作得很好。

+1

很高興看到你去了XML :: LibXML路線。要習慣XML的嚴格性有點困難,但從長遠來看,它將爲您節省大量時間。 (我不得不與那些在實現XML時使用捷徑的供應商合作,這意味着我實際上不能給他們XML,我不得不給他們一些標籤湯,非常惱人。) – jrockway 2009-06-14 12:49:55

回答

5

一個辦法是改變你的reversesort聲明(未經測試):

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')) { 
    ... 
} 

希望這有助於一點!

+0

啊,我現在看到了,我想。 .. $ a和$ b是兩個單獨的條目,對嗎?但是,我怎樣才能以編程方式瀏覽所有條目?有些文件有數百個條目... – Andrew 2009-06-13 12:45:15

+0

我仍然沒有得到$ a和$ b的來源... – Andrew 2009-06-13 13:58:46

2

裸排序可能把從不同的時區超時的順序:

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

在這裏,第二時間爲3小時後的第一個,但首先進行排序。

我不確定你的意思是「wonky」。您的示例僅顯示rfc3339格式的時間戳。

相關問題