2015-08-18 66 views
4

我有一些JSON和D3的小提琴,試圖以'泡泡'風格表示一些磁盤使用信息。基於在perl中構建有序的JSON

這個最初:http://bl.ocks.org/mbostock/4063269

的JSON是很簡單 - 分層數據看起來有點像這樣:

http://bl.ocks.org/mbostock/raw/4063530/flare.json

{ 
"name": "flare", 
"children": [ 
    { 
    "name": "analytics", 
    "children": [ 
    { 
    "name": "cluster", 
    "children": [ 
     {"name": "AgglomerativeCluster", "size": 3938}, 
     {"name": "CommunityStructure", "size": 3812}, 
     {"name": "HierarchicalCluster", "size": 6714}, 
     {"name": "MergeEdge", "size": 743} 
    ] 
    } 
    ] 
    } 
] 
} 

現在,我什麼試圖到做的是從NetApp獲取quotas報告 - 以XML格式。

我看幾乎相當於多個「每個服務器的XML文件:

<quotas> 
    <quota> 
    <quota-target>/vol/vol1/qtree1</quota-target> 
    <volume>vol1</volume> 
    <disk-used>554444</disk-used> 
    <disk-limit>2000000</disk-limit> 
    </quota> 
    <quota> 
    <quota-target>/vol/vol1/qtree2</quota-target> 
    <volume>vol1</volume> 
    <disk-used>1235655</disk-used> 
    <disk-limit>2000000</disk-limit> 
    </quota> 
    <quota> 
    <quota-target>/vol/vol2/qtree1</quota-target> 
    <volume>vol2</volume> 
    <disk-used>987664</disk-used> 
    <disk-limit>2000000</disk-limit> 
    </quota> 
</quotas> 

我試圖做的是組裝一些JSON與D3這就是分層使用:

  • 網站
  • 服務器
  • 體積
  • 配額目標
  • 磁盤使用的

我做的不錯了foreach循環:

#!/usr/bin/env perl 
use strict; 
use warnings; 
use XML::Twig; 
use JSON; 

my %sites = (
    'site1' => [qw (servera serverb)], 
    'site2' => [qw (s2serverc s2serverd)], 
); 

my $data; 
$data->{'name'} = "quotas"; 
foreach my $sitename (keys %sites) { 
    my $site = { 'name' => $sitename }; 
    push(@{ $data->{'children'} }, $site); 
    foreach my $server (@{ $sites{$sitename} }) { 
     my $server = { 'name' => $server }; 
     push(@{ $site->{'children'} }, $server); 

     $twig->parsefile("$server.quotas.xml"); 
     foreach my $quota ($twig->get_xpath('//quota')) { 
      push(
       @{ $server->{'children'} }, 
       { 'name' => $quota->first_child_text('quota-target'), 
        'size' => $quota->first_child_text('disk-used') 
       } 
       ) 

     } 
    } 
} 

open(my $output, ">", "quotas.json") or die $!; 
print {$output} to_json($data, { 'pretty' => 1 }); 
close($output); 

這是廣泛的合作,併產生了我漂亮的圖片。

但是我有兩個問題:JSON的

命令改變每次運行,因爲我使用的哈希值。雖然不是一個展示器 - 有沒有一種方法可以在JSON輸出中執行訂單? (不一定是按字母順序排序)

同樣 - 我正在研究如何插入當前不存在的'音量'級節點,因爲我正在創建新的匿名哈希以插入到每個children層的foreach循環。這感覺有點笨重,但我在想的是:

  • get_xpath('//volume')提取卷的列表並對其進行了唯一化。
  • 要麼迭代per volume匹配,找到子節點(是否有xpath表達式指定一個孩子的價值?)
  • 或者創建散列的「分期」散,我則「合併」成JSON的children

有沒有人有更好的建議?

我可以很容易地創建所需結構的散列,例如

$stuff{$site}{$server}{$volume}{$qtree} = $size; 

但是,然後將不得不把它變成適當的JSON(我認爲這可能是一個更好的方法總體)。

+2

您的問題似乎包含多個問題。 – ikegami

回答

1

有沒有辦法在JSON輸出中強制執行命令?

是的,使用數組而不是對象。 JSON對象是無序的。

對象對象是一組無名的名稱/值對。

但似乎你已經在使用數組作爲你的列表。

也許你想要能夠執行差異,在這種情況下,JSON.pm提供了以sort_by的形式指定密鑰的粗略方法。如果你想執行差異有用。

0

如果您只是想通過散列鍵「執行」某些排序,則可以使用「規範」功能,也可以使用here