将散列转换为json,用于cisco cdp拓扑的D3树形图

时间:2012-12-17 18:19:33

标签: json perl d3.js cisco

在我的perl脚本中,我通过SNMP(在这种情况下是设备的IP地址)从我的网络中的cisco路由器收集CDP邻居信息来填充二维哈希。哈希允许我限制重复并捕捉父母的女儿关系。

$name{$hostIP}{$neighbourIP} = $name;

我想将散列数据与D3.js(在树形图中)一起使用来说明路由器拓扑或连接关系,并且需要递归地以JSON格式化的数据,如:

{
 name: "10.120.5.1",
 children: [
  {
   name: "10.120.5.2",
   children: [
    {
     name: "10.120.5.3",
     children: [
      {
       name: "10.120.5.4"
      },
      {
       name: "10.120.6.1"
      },
      {
       name: "10.120.6.2"
      },
      {
       name: "10.120.6.3"
      }
     ]
    }
   ]
  }
 ]
}

有人可以提供使用库或普通打印语句的示例,显示如何将哈希格式转换为类似于上面的JSON吗? Perl是首选,但任何语言如python,C都会有所帮助。此外,如果有人知道任何开源脚本已经完成这项工作,我很乐意比较。

2 个答案:

答案 0 :(得分:1)

使用JSON模块。

https://metacpan.org/pod/JSON

使用JSON;

我的$ json = JSON-> new();

my $ json_string = $ json-> encode($ hash_to_send_to_d3)

答案 1 :(得分:1)

这对递归有帮助吗?从类似于你的哈希开始,我执行

  • 广度优先搜索,查看哪些孩子可以与哪些父母一起列出
  • 接着是该中间结构的深度优先演练,以构建与json示例等效的哈希
  • 然后直接转到json。

将数据移动两次似乎​​不是最佳的,但不这样做会导致非常深的树形图。

#!/bin/perl

use 5.010; # Enable 'say'. Sorry, old perl
use strict;
use warnings;
use JSON::PP; # Just 'use JSON;' on most systems

# 0. set up some data in adjacency table
my %name;
$name{'10.120.5.1'}{'10.120.5.2'}++;
$name{'10.120.5.2'}{'10.120.5.1'}++;

$name{'10.120.5.2'}{'10.120.5.3'}++;
$name{'10.120.5.3'}{'10.120.5.2'}++;

$name{'10.120.5.3'}{'10.120.5.4'}++;
$name{'10.120.5.4'}{'10.120.5.3'}++;

$name{'10.120.5.3'}{'10.120.6.1'}++;
$name{'10.120.6.1'}{'10.120.5.3'}++;

$name{'10.120.5.3'}{'10.120.6.2'}++;
$name{'10.120.6.2'}{'10.120.5.3'}++;

$name{'10.120.5.3'}{'10.120.6.3'}++;
$name{'10.120.6.3'}{'10.120.5.3'}++;


# 1. set up helper structures
# pick a starting point
(my $root) = keys %name;

# empty structures
my %nodes = ();
my %tree  = ();
my @queue = ($root);

# 2. First pass: BFS to determine child nodes 
list_children(\%name, \@queue, \%nodes) while @queue;

# 3. Second pass: DFS to set up tree
my $tree = build_tree($root, \%nodes);

# 4. And use JSON to dump that data structure
my $json = JSON::PP->new->pretty; # prettify for human consumption

say $json->encode($tree);

sub list_children {
  my $adjac = shift;
  my $queue  = shift;
  my $nodes  = shift;

  my $node = shift @$queue;

  # all child nodes
  my @children = keys %{$adjac->{$node}};

  # except the ones we visited earlier, to avoid loops
  @children = grep { ! exists $nodes->{$_}} @children;

  $nodes->{$node} = \@children;

  # and toss on the queue
  push @$queue, @children;
}

sub build_tree {
  my $root  = shift;
  my $nodes = shift;

  my @children;
  for my $child (@{$nodes->{$root}}) {
    push @children, build_tree($child, $nodes);
  }

  my %h = ('name'     => $root,
           'children' => \@children);

  return \%h;
}