1

在我的 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 都会有所帮助。此外,如果有人知道已经完成这项工作的任何开源脚本,我很乐意进行比较。

4

2 回答 2

1

使用 JSON 模块。

https://metacpan.org/pod/JSON

使用 JSON;

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

我的 $json_string = $json->encode( $hash_to_send_to_d3 )

于 2012-12-17T18:23:06.693 回答
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;
}
于 2012-12-18T15:47:05.067 回答