【问题标题】:find parent for a json object using jsonpath-ng使用 jsonpath-ng 查找 json 对象的父对象
【发布时间】:2020-03-15 05:19:45
【问题描述】:

我有一个像下面这样的 json obj。我需要找到所有的“声明”和各自的父母。我能够找到“声明”。但是,不知道如何提取它们各自的父级。我正在使用 Python3,jsonpath_ng。到目前为止,这是我的代码:

from jsonpath_ng import jsonpath, parse
from pprint import pprint

       x = {'MasterRole': {'Type': 'AWS::IAM::Role',
          'Properties': {'Path': '/',
           'AssumeRolePolicyDocument': {'Version': '2012-10-17',
            'Statement': [{'Action': ['sts:AssumeRole'],
              'Principal': {'Service': ['ec2.amazonaws.com']},
              'Effect': 'Allow'}]},
           'Policies': [{'PolicyDocument': {'Version': '2012-10-17',
              'Statement': [{'Action': ['s3:AbortMultipartUpload',
                 's3:DeleteObject',
                 's3:PutObjectAcl'],
                'Resource': [{'Fn::Join': ['',
                   ['arn:aws:s3:::', {'Ref': 'ExhibitorS3Bucket'}, '/*']]},
                 {'Fn::Join': ['', ['arn:aws:s3:::', {'Ref': 'ExhibitorS3Bucket'}]]}],
                'Effect': 'Allow'},
               {'Action': ['cloudformation:*'],
                'Resource': [{'Ref': 'AWS::StackId'},
                 {'Fn::Join': ['', [{'Ref': 'AWS::StackId'}, '/*']]}],
                'Effect': 'Allow'}]}}]}}}

In [40]: res = [match.value for match in parse('$..Statement').find(x)]

In [41]: pprint(res)
[[{'Action': ['sts:AssumeRole'],
   'Effect': 'Allow',
   'Principal': {'Service': ['ec2.amazonaws.com']}}],
 [{'Action': ['s3:AbortMultipartUpload', 's3:DeleteObject', 's3:PutObjectAcl'],
   'Effect': 'Allow',
   'Resource': [{'Fn::Join': ['',
                              ['arn:aws:s3:::',
                               {'Ref': 'ExhibitorS3Bucket'},
                               '/*']]},
                {'Fn::Join': ['',
                              ['arn:aws:s3:::',
                               {'Ref': 'ExhibitorS3Bucket'}]]}]},
  {'Action': ['cloudformation:*'],
   'Effect': 'Allow',
   'Resource': [{'Ref': 'AWS::StackId'},
                {'Fn::Join': ['', [{'Ref': 'AWS::StackId'}, '/*']]}]}]]

In [42]:

预期的父母:“AssumeRolePolicyDocument”和“PolicyDocument”。不胜感激如何接父母。我无法理解如何从上下文数据中解析内容。以下是我如何获得“DatumInContext”(之后,我迷路了)。

In [18]: res = parse('$..Statement').find(x)
In [19]: pprint(res)
[DatumInContext(value=[{'Action': ['sts:AssumeRole'], 'Principal': {'Service': ['ec2.amazonaws.com']}, 'Effect': 'Allow'}], path=Fields('Statement'), context=DatumInContext(value={'Version': '2012-10-17', 'Statement': [{'Action': ['sts:AssumeRole'], 'Principal': {'Service': ['ec2.amazonaws.com']} ......

对于每个“声明”,恰好给出了 2 个上下文(如预期的那样)。而且,这些上下文有丰富的信息,有完整的路径等等。但是,我不知道如何获得父母的名字。我不知道如何使用各种函数,如 jsonPath.parent()、jsonPath.parent.find(),关于此的文档很少甚至为零。

有什么帮助吗?

【问题讨论】:

    标签: python-3.x jsonpath-ng


    【解决方案1】:

    可能是一个 hacky 解决方案,但它对我有用。我被困在你所在的地方。 试试这个:

    res = [str(match.context.path) for match in parse('$..Statement').find(x)]
    

    让我试着解释一下我是如何得出这个解决方案的。 如果您像以前一样打印匹配对象本身

    In [18]: res = parse('$..Statement').find(x)
    In [19]: pprint(res)
    

    您会看到它有多个键(为简单起见,将其视为 json),而键 value 是您在执行 match.value 时得到的。现在,检查还有其他键,context 就是其中之一。如果你仔细看context的内容,你会发现它包含了该层(Statement所在层)全节点的json。

    context 键内,您将看到另一个键path。如果你做 match.context.path,它应该转储父对象。

    你是对的,文档非常少,因此不得不破解它。

    【讨论】:

      【解决方案2】:

      你可以在 jsonpath 表达式中直接使用 parent 关键字

      res = parse('$..Statement.`parent`').find(x)
      

      因此

      pprint( { str(m.path) : m.value["Statement"]  for m in res } )
      

      给予

      {'AssumeRolePolicyDocument': [{'Action': ['sts:AssumeRole'],
                                     'Effect': 'Allow',
                                     'Principal': {'Service': ['ec2.amazonaws.com']}}],
       'PolicyDocument': [{'Action': ['s3:AbortMultipartUpload',
                                      's3:DeleteObject',
                                      's3:PutObjectAcl'],
                           'Effect': 'Allow',
                           'Resource': [{'Fn::Join': ['',
                                                      ['arn:aws:s3:::',
                                                       {'Ref': 'ExhibitorS3Bucket'},
                                                       '/*']]},
                                        {'Fn::Join': ['',
                                                      ['arn:aws:s3:::',
                                                       {'Ref': 'ExhibitorS3Bucket'}]]}]},
                          {'Action': ['cloudformation:*'],
                           'Effect': 'Allow',
                           'Resource': [{'Ref': 'AWS::StackId'},
                                        {'Fn::Join': ['',
                                                      [{'Ref': 'AWS::StackId'},
                                                       '/*']]}]}]}
      

      【讨论】:

        猜你喜欢
        • 2016-05-27
        • 1970-01-01
        • 2022-01-05
        • 1970-01-01
        • 2020-06-29
        • 2023-02-01
        • 2020-04-19
        • 1970-01-01
        • 2018-08-30
        相关资源
        最近更新 更多