关于循环使用json2dict转换的字典的想法

时间:2015-09-27 18:04:00

标签: json tcl

我正在努力想出最好的方法来显示我使用json2dict转换的dict内部的两个值。以下是我调用的返回代码的基本格式:

{
"templates": [
    {
        "title": "Title1",
        "uuid": "123-456-789",
        "key_dont_need": "value"
    },
    {
        "key_dont_need": "value"
        "title": "Title2",
        "uuid": "acr-t54-g32",
    },
    {
        "title": "Network Scan",
        "key_dont_need": "value"
        "uuid": "5ge-534-3g3"
    }
  ]
}

我要做的是取出每个标题和uuid。我已经设法让它拿出第一个头衔/ uuid,但之后我没有取得多大成功。这是我目前的代码(请在必要时销毁它,我仍在学习,并希望得到反馈):

package require rest
package require tls
package require json

::http::register https 443 ::tls::socket


proc login {url credentials} {
    append url /session
    set unformattedToken [dict get [::json::json2dict [::rest::post $url $credentials]] token]
    set token [format "token=%s" $unformattedToken] 
    return $token
}

proc logout {url config} {
    append url /session
    set logout [::rest::delete $url -headers $config]
}

proc get_scan_list {url config} {
    append url /scans
    set response [::rest::get $url -headers $config]
    return $response
}

proc get_scan_policies {url config} {
    append url /editor/policy/templates
    set policy_list [::rest::get $url -headers $config]]
    dict get [lindex [dict get [::json::json2dict $policy_list] templates] 0] title
}

set url https://127.0.0.1:8834
set credentials {username admin password myPassword}
set token [login $url $credentials]
dict set config headers X-Cookie $token
set scan_list [get_scan_list $url $config]
set scan_policies [get_scan_policies $url $config]

我正试图想出最好的方法来增加这些uuids,但我遇到了一些障碍。

以下是我尝试过的几种方法:

dict for {id templates} $policy_list {
        puts "Policy Name: $title"
        puts "Policy UUID: $uuid"
    }

我也试过这个想法: http://wiki.tcl.tk/19941

但我也没有太多运气。从Python的角度来看,这基本上就是我要做的事情:

def get_policies():
"""
Get scan policies

Get all of the scan policies but return only the title and the uuid of
each policy.
"""

data = connect('GET', '/editor/policy/templates')

return dict((p['title'], p['uuid']) for p in data['templates'])

我开始怀疑我的问题是否与数据转换为json2dict后的存储方式有关?我可能会离开那里。

编辑

就像我点击提交一样,我设法让它与之合作:

proc get_scan_policies {url config} {
    append url /editor/policy/templates
    set policy_list [::rest::get $url -headers $config]
    for {set i 0} {$i < 17} {incr i} {
        puts [dict get [lindex [dict get [::json::json2dict $policy_list] templates] $i] uuid]
        puts [dict get [lindex [dict get [::json::json2dict $policy_list] templates] $i] title]
    }
}

这是我的输出:

Policy Name: Title1
Policy UUID: 123-456-789
Policy Name: Title2
Policy UUID: acr-t54-g32
Policy Name: Network Scan
Policy UUID: 5ge-534-3g3

我在那里对计数进行了硬编码,但我很想知道是否有更好的方法可以做到这一点。

2 个答案:

答案 0 :(得分:3)

更正了json:

set json {{
"templates": [
    {
        "title": "Title1",
        "uuid": "123-456-789",
        "key_dont_need": "value"
    },
    {
        "key_dont_need": "value",
        "title": "Title2",
        "uuid": "acr-t54-g32"
    },
    {
        "title": "Network Scan",
        "key_dont_need": "value",
        "uuid": "5ge-534-3g3"
    }
  ]
}}

转换为Tcl dict

package require json

set policy_list [::json::json2dict $json]

仅使用dicttitle密钥获取新的uuid

lmap item [dict get $policy_list templates] {
    dict filter $item key title uuid
}

打印titleuuid键的值:

foreach item [dict get $policy_list templates] {
    dict with item {
        puts "Policy Name: $title"
        puts "Policy UUID: $uuid"
    }
}

你要开始的是一个带有一个键(templates)和一个值的json对象,它是一个数组。数组中的每个项都是一个包含三个键的对象(titleuuidkey_dont_need)。要访问此结构中的内部值,您需要dict访问操作,列表映射/迭代操作以及每个项目的dict访问操作。

dict get $policy_list templates

让你进入外部对象。

foreach item ... script

允许您遍历数组中的每个项目;

lmap item ... script

允许您映射在每个项目上,返回一个新列表,其中包含每个脚本评估的结果。

dict filter dict-value key k1 k2 ...

创建一个dict,其中包含另一个dict的成员,这些成员的密钥与k1k2,...参数所指定的键匹配(他们可以拥有glob形式,例如foo*)。

dict with dict-variable script

(它也可以使用键,但不需要它们)基本上使用新创建的变量来评估脚本,这些变量具有键的名称和值的值。

文档:dictforeachjson包,lmaplmap替代,packageputs,{ {3}}

答案 1 :(得分:1)

您可以尝试这种方法,而不是硬编码17:

proc get_scan_policies {url config} {
    append url /editor/policy/templates
    set policy_list [::rest::get $url -headers $config]
    set len [llength $policy_list]
    for {set i 0} {$i < $len} {incr i} {
        puts [dict get [lindex [dict get [::json::json2dict $policy_list] templates] $i] uuid]
        puts [dict get [lindex [dict get [::json::json2dict $policy_list] templates] $i] title]
    }
}