在perl

时间:2015-08-18 11:00:56

标签: json perl d3.js

我对JSON和D3有点小提琴,试图在“泡泡”中表示一些磁盘使用信息。样式。

最初基于此: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输出中强制执行订单? (不一定只是按字母顺序排序)

同样 - 我正在研究如何插入&#39;卷&#39;当前不存在的关卡节点,因为我创建了新的匿名哈希值,以便在children循环的每一层插入foreach。这感觉有点笨拙,但我在想的是:

  • 使用get_xpath('//volume')提取卷列表并使其唯一化。
  • 迭代per volume查找匹配的子节点(是否有xpath表达式来指定子值?)
  • 或者创建一个&#39; staging&#39;我然后合并的哈希哈希&#39;进入JSON中的children

有没有人有更好的建议?

我可以很容易地创建所需结构的哈希,例如

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

但是那时必须把它变成适当的JSON(我想这可能是一个更好的方法)。

2 个答案:

答案 0 :(得分:1)

  

有没有办法在JSON输出中强制执行订单?

是的,使用数组而不是对象。 JSON对象是无序的。

  

对象是一组无序的名称/值对。

但似乎您已经在列表中使用了数组。

也许您希望能够执行差异,在这种情况下,JSON.pm提供了一种以sort_by形式指定密钥的粗略方法。如果你想执行差异,这很有用。

答案 1 :(得分:0)

如果您只想通过哈希键“强制”进行某些排序,则可以使用“规范”功能,也可以使用here