简体   繁体   English

提取嵌套JSON对象的模式

[英]Extract schema of nested JSON object

Let's assume this is the source json file: 我们假设这是源json文件:

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

I want to get: 我想得到:

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

I am able to extract the keys using: jq '. | keys' file.json 我可以使用: jq '. | keys' file.json提取密钥jq '. | keys' file.json jq '. | keys' file.json jq '. | keys' file.json , but this skips nested fields. jq '. | keys' file.json ,但这会跳过嵌套字段。 How to include those? 如何包括那些?

With your input, the invocation: 根据您的输入,调用:

jq 'leaf_paths | join(".")'

produces: 生产:

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

If you want to include "visits", use paths . 如果要包含“访问次数”,请使用paths If you want the result as a JSON array, enclose the filter with square brackets: [ ... ] 如果您希望将结果作为JSON数组,请使用方括号括起过滤器:[...]

If your input might include arrays, then unless you are using jq 1.6 or later, you will need to convert the integer indices to strings explicitly; 如果您的输入可能包含数组,那么除非您使用的是jq 1.6或更高版本,否则您需要将整数索引显式转换为字符串; also, since leaf_paths is now deprecated, you might want to use its def. 此外,由于现在不推荐使用leaf_paths ,您可能希望使用其def。 The result: 结果:

jq 'paths(scalars) | map(tostring) | join(".")'

allpaths allpaths

To include paths to null, you could use allpaths defined as follows: 要包含null的路径,可以使用allpaths定义的allpaths

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

Example: 例:

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

produces: 生产:

"a"
"b"

all_leaf_paths all_leaf_paths

Assuming jq version 1.5 or higher, we can get to all_leaf_paths by following the strategy used in builtins.jq, that is, by adding these definitions: 假设jq版本1.5或更高版本,我们可以通过遵循all_leaf_paths使用的策略来获取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);

Example: 例:

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

produces: 生产:

"a"
"b"
"object.x"

This does what you want but it doesn't return the data in an array, but it should be an easy modification: 这样做你想要的,但它不会返回数组中的数据,但它应该是一个简单的修改:

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

you can also check out this page: https://ilya-sher.org/2016/05/11/most-jq-you-will-ever-need/ 你也可以看看这个页面: https//ilya-sher.org/2016/05/11/most-jq-you-will-ever-need/

Some time ago, I wrote a structural-schema inference engine that produces simple structural schemas that mirror the JSON documents under consideration, eg for the sample JSON given here, the inferred schema is: 前段时间,我编写了一个结构模式推理引擎,它生成了镜像所考虑的JSON文档的简单结构模式,例如,对于此处给出的示例JSON,推断的模式是:

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

This is not exactly the format requested in the original posting, but for large collections of objects, it does provide a useful overview. 这不完全是原始发布中请求的格式,但对于大型对象集合,它确实提供了有用的概述。

More importantly, there is now a complementary validator for checking whether a collection of JSON documents matches a structural schema. 更重要的是,现在有一个补充验证器,用于检查JSON文档集合是否与结构模式匹配。 The validator checks against schemas written in JESS (JSON Extended Structural Schemas), a superset of the simple structural schemas (SSS) produced by the schema inference engine . 验证器检查用JESS (JSON扩展结构模式)编写的模式, JESS扩展结构模式是模式推理引擎生成的简单结构模式(SSS)的超集。

(The idea is that one can use the SSS as a starting point to add more elaborate constraints, including recursive constraints, within-document referential integrity constraints, etc.) (我们的想法是,可以使用SSS作为起点来添加更复杂的约束,包括递归约束,文档内参照完整性约束等)。

For reference, here is how one the SSS for your sample.json would be produced using the "schema" module : 作为参考,以下是使用“schema”模块生成sample.json的SSS的方法:

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

And to validate source.json against a SSS or ESS: 并针对SSS或ESS验证source.json:

JESS --schema  source.schema.json  source.json

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM