【问题标题】:Generate JSON from nested sets (perl, sql, jquery)从嵌套集(perl、sql、jquery)生成 JSON
【发布时间】:2011-02-03 09:22:23
【问题描述】:

我在数据库中有内容页面(使用嵌套集),我需要通过 jQuery jsTree 插件显示它。它需要返回带有如下数据的 JSON:

[
    {
        data: 'node1Title',
        children: [
            {
                data: 'subNode1Title',
                children: [...]
            },
            {
                data: 'subNode2Title',
                children: [...]
            }
        ]
    },
    {
        data: 'node2Title',
        children: [...]
    }
]

我需要做什么?

我可以将哈希数组转换为 JSON,但我不明白如何生成数组。

样本数据:

**'pages'table**
id  parent_id   level   lkey    rkey    name
1   0       1   1   14  index
2   1       2   2   7   info
3   1       2   8   13  test
4   2       3   3   4   about
5   2       3   5   6   help
6   3       3   9   10  test1
7   3       3   11  12  test2

我需要得到:

[
    {
        data: 'index',
        children: [
            {
                data: 'info',
                children: [
                    {
                        data: 'about'
                    },
                    {
                        data: 'help',
                    }
                ]
            },
            {
                data: 'test',
                children: [
                    {
                        data: 'test1'
                    },
                    {
                        data: 'test2'
                    }
                ]
            }
        ]
    }
]

【问题讨论】:

  • 请澄清您的问题。您需要从 Perl 生成 JSON 吗?您能否发布您拥有的数据样本以及您已经提供的输出?

标签: sql json jstree nested-sets


【解决方案1】:

我遇到了完全相同的问题,这是我在 Perl 中编写的,用于将我的嵌套集树转换为 jsTree 插件的 JSON 对象(我使用 DBIx::Tree::NestedSet 来访问 MySQL 数据库树)。我知道我的代码从 Perl 的角度来看很难看,但它对我有用。

sub get_json_tree {
    my $json = '[';
    my $first = 1;
    my $last_level = 1;
    my $level = 1;
    my $tree = DBIx::Tree::NestedSet->new(dbh => $dbh);
    my $ancestors = $tree->get_self_and_children_flat(id => $tree->get_root);
    foreach (@{$ancestors}) {
        my $name = $_->{'name'};
        $last_level = $level;
        $level = $_->{'level'};
        if ($level > $last_level) {
            $json .= ',' if ($json =~ /}$/);
        } elsif ($level < $last_level) {
            $json .= ']}';
            for (my $i = 0; $i < $last_level - $level; $i++) {
                $json .= ']}';
            }
            $json .= ',';
        } elsif ($level == $last_level && !$first) {
            $json .= ']},';
        }
        $json .= '{"attr":{"id":'.$_->{'id'}.',"rel":"folder"},"data":"'.$name.'","children":[';
        $first = 0;
    }
    $json .= ']}';
    for (my $i = 1; $i < $level; $i++) {
        $json .= ']}';
    }    
    $json .= ']';
    return $json;
}

【讨论】:

    【解决方案2】:

    我正在寻找它。也许 DataTable 插件示例提供了一个解决方案。我正在查看插件目录/examples/server_side/scripts/ssp.class.php。你可以download it here

    this documentation 中的“服务器端脚本”标签中查看最简单的使用方法。

    【讨论】:

      【解决方案3】:

      这很简单。您需要编写一个递归函数。我用 Perl 写的。 $list - 这是按“left_key”排序的数组。

      sub make_tree {
          my $list = shift;
          my @nodes;
      
          while (my $node = shift @$list) {
              if (@$list and $node->{level} < $list->[0]{level}) {
                  $node->{data} = make_tree($list);
                  push @nodes, $node;
              }
              last if @$list and $node->{level} > $list->[0]{level};
          }
      
          return \@nodes;
      }
      
      my $hash = make_tree($list);
      

      【讨论】:

        【解决方案4】:

        最近我正在寻找类似的解决方案。直到发布我自己的问题后,我才发现这一点。我在问题上发布的最终代码我认为可以很好地回答您的问题。

        我将以下代码与 DBIx::Tree::NestedSet 的修改版本一起使用。我使用此代码创建嵌套集树的 JSON 输出。

        Convert a flat datastructure into a tree

        sub get_jsonTree {
            my ($array_of_hashes_ref) = @_;
        
            my $roots;
            my %recs_by_name;
            my %children_by_parent_name;
            my %count;
            for my $row (@$array_of_hashes_ref) {
                my $name        = $row->{position_id};
                my $parent_name = $row->{placement_id};
        
                my $rec = {
                    name => $name,
                };
        
                ## Added to loop through all key,value pairs and add them to $rec
                while ( my ($key, $value) = each(%$row) ) {
                    $rec->{$key} = $value;
                }
        
                ##Added To Count Child Nodes
                $count{$parent_name} = 0 if (!$count{$parent_name});        
                $rec->{'child_count'} = $count{$parent_name};
                $count{$parent_name}++;
        
                push @{ $children_by_parent_name{$parent_name // 'root'} }, $rec;
                $recs_by_name{$name} = $rec;
            }
        
            $roots = delete($children_by_parent_name{root}) || [];
        
            for my $name (keys(%children_by_parent_name)) {
                my $children = $children_by_parent_name{$name};
                if ( my $rec = $recs_by_name{$name} ) {
                    $rec->{children} = $children;
                } else {
                    $util{'test'} .=  "Parent $name doesn't exist.\n<BR>";
                    push @$roots, @$children;
                }
            }
        
            use JSON;
            my $json_str = encode_json(@{$roots}[0]);
        
            return $json_str;
        }
        
        my $array_of_hashes_ref = [
            {  position_id => 123, placement_id => undef },
            {  position_id => 456, placement_id => 123 },
            {  position_id => 789, placement_id => 123 },
            # ...
        ];
        
        my $json_str = &get_jsonTree($array_of_hashes_ref);
        

        【讨论】:

          猜你喜欢
          • 2015-06-12
          • 1970-01-01
          • 1970-01-01
          • 2011-09-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多