提取嵌套JSON对象的模式

时间:2017-04-12 21:09:08

标签: json nested key jq

我们假设这是源json文件:

{    
    "name": "tom",
    "age": 12,
    "visits": {
        "2017-01-25": 3,
        "2016-07-26": 4,
        "2016-01-24": 1
    }
}

我想得到:

[
  "age",
  "name",
  "visits.2017-01-25",
  "visits.2016-07-26",
  "visits.2016-01-24"
]

我可以使用jq '. | keys' file.json提取密钥,但这会跳过嵌套字段。如何包含这些?

3 个答案:

答案 0 :(得分:4)

根据您的输入,调用:

jq 'leaf_paths | join(".")'

产生

"name"
"age"
"visits.2017-01-25"
"visits.2016-07-26"
"visits.2016-01-24"

如果您想加入“访问次数”,请使用paths。如果您希望将结果作为JSON数组,请使用方括号括起过滤器:[...]

allpaths

要包含null的路径,可以使用allpaths定义如下:

def allpaths:
  def conditional_recurse(f):  def r: ., (select(.!=null) | f | r); r;
  path(conditional_recurse(.[]?)) | select(length > 0);

示例:

{"a": null, "b": false} | allpaths | join(".")

产生

"a"
"b"

all_leaf_paths

假设jq版本1.5或更高版本,我们可以按照builtins.jq中使用的策略,即添加以下定义来到all_leaf_paths

def allpaths(f):
  . as $in | allpaths | select(. as $p|$in|getpath($p)|f);

def isscalar:
  . == null or . == true or . == false or type == "number" or type == "string";

def all_leaf_paths: allpaths(isscalar);

示例:

{"a": null, "b": false, "object":{"x":0} } | all_leaf_paths | join(".")

产生

"a"
"b"
"object.x"

答案 1 :(得分:0)

这可以满足您的需求,但它不会返回数组中的数据,但它应该是一个简单的修改:

https://github.com/ilyash/show-struct

您还可以查看此页面: https://ilya-sher.org/2016/05/11/most-jq-you-will-ever-need/

答案 2 :(得分:0)

前一段时间,我写了一个结构模式推论引擎, 产生简单的结构化模式,以反映所考虑的JSON文档, 例如对于此处给出的示例JSON,推断的架构为:

QUrl url("https://pos-api.ifood.com.br/oauth/token");
QUrlQuery q;
q.addQueryItem("client_id", id); 
q.addQueryItem("client_secret", secret); 
q.addQueryItem("grant_type","password"); 
q.addQueryItem("username",user); 
q.addQueryItem("password",password); 

url.setQuery(q);

QtCUrl::Options opt;
opt[CURLOPT_URL] = url;
opt[CURLOPT_POST] = true;
opt[CURLOPT_FOLLOWLOCATION] = true;
opt[CURLOPT_FAILONERROR] = true;


opt[CURLOPT_SSL_VERIFYPEER]= false;  // windows

QStringList headers;
headers
    << "cache-control: no-cache"
    << "content-type: application/x-www-form-urlencoded";
opt[CURLOPT_HTTPHEADER] = headers;
val = cUrl.exec(opt);  // PROBLEM HERE!!!!

if (cUrl.lastError().isOk()) {

    bool ok;
    // json is a QString containing the JSON data
    QtJson::JsonObject result = QtJson::parse(val, ok).toMap();
    token=result["access_token"].toString();


    return token;
}
else {
    return "";
}

这与原始过帐中要求的格式不完全相同,但是 对于大量对象,它的确提供了有用的概述。

更重要的是,现在有一个补充验证器 检查JSON文档的集合是否与结构 模式。验证器检查写入的模式 JESS(JSON扩展结构模式),是简单的超集 模式推导引擎生成的结构化模式(SSS)。

(想法是,可以使用SSS作为起点添加 更复杂的约束,包括递归约束, 文档内参照完整性约束等)

作为参考,这是您的sample.json的SSS的方式 将使用"schema" module生成:

{
  "name": "string",
  "age": "number",
  "visits": {
    "2017-01-25": "number",
    "2016-07-26": "number",
    "2016-01-24": "number"
  }
}

并针对SSS或ESS验证source.json:

jq 'include "schema"; schema' source.json > source.schema.json