简体   繁体   English

Python 解析 JSON 文件

[英]Python parse JSON file

{
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft": "Warning",
            "Microsoft.Hosting.Lifetime": "Information",
            "Microsoft.AspNetCore": "Warning",
            "System.Net.Http.HttpClient.Default.ClientHandler": "Warning",
            "System.Net.Http.HttpClient.Default.LogicalHandler": "Warning"
        }
    },
    "AllowedHosts": "*",
    "AutomaticTransferOptions": {
        "DateOffsetForDirectoriesInDays": -1,
        "DateOffsetForPortfoliosInDays": -3,
        "Clause": {
            "Item1": "1"
        }    
    },
    "Authentication": {
        "ApiKeys": [
            {
                "Key": "AB8E5976-2A7C-4EEE-92C1-7B0B4DC840F6",
                "OwnerName": "Cron job",
                "Claims": [
                    {
                        "Type": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
                        "Value": "StressTestManager"
                    }
                ]
            },
            {
                "Key": "B11D4F27-483A-4234-8EC7-CA121712D5BE",
                "OwnerName": "Test admin",
                "Claims": [
                    {
                        "Type": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
                        "Value": "StressTestAdmin"
                    },
                    {
                        "Type": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
                        "Value": "TestManager"
                    }
                ]
            },
            {
                "Key": "EBF98F2E-555E-4E66-9D77-5667E0AA1B54",
                "OwnerName": "Test manager",
                "Claims": [
                    {
                        "Type": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
                        "Value": "TestManager"
                    }
                ]
            }
        ],
        "LDAP": {
            "Domain": "domain.local",
            "MachineAccountName": "Soft13",
            "MachineAccountPassword": "vixuUEY7884*",
            "EnableLdapClaimResolution": true
        }
    },
    "Authorization": {
        "Permissions": {
            "Roles": [
                {
                    "Role": "TestAdmin",
                    "Permissions": [
                        "transfers.create",
                        "bindings.create"
                    ]
                },
                {
                    "Role": "TestManager",
                    "Permissions": [
                        "transfers.create"
                    ]
                }
            ]
        }
    }
}

I have JSON above and need to parse it with output like this我上面有 JSON 需要像这样用 output 解析它

Logging__LogLevel__Default
Authentication__ApiKeys__0__Claims__0__Type

Everything is ok, but I always get some strings with this output一切都很好,但我总是用这个 output 得到一些字符串

Authentication__ApiKeys__0__Key
Authentication__ApiKeys__0__OwnerName
Authentication__ApiKeys__0__Claims__0__Type
Authentication__ApiKeys__0__Claims__0__Value
Authentication__ApiKeys__0__Claims__0
Authentication__ApiKeys__2
Authorization__Permissions__Roles__0__Role
Authorization__Permissions__Roles__0__Permissions__1
Authorization__Permissions__Roles__1__Role
Authorization__Permissions__Roles__1__Permissions__0
Authorization__Permissions__Roles__1

Why does my code adds not full strings like为什么我的代码不添加完整的字符串

Authentication__ApiKeys__0__Claims__0
Authentication__ApiKeys__2
Authorization__Permissions__Roles__1

And why it doesn't print every value from以及为什么它不打印每个值

Authorization__Permissions__Roles__0__Permissions__*

and from并从

Authorization__Permissions__Roles__1__Permissions__*

I have this code in python3:我在python3中有这段代码:

def checkdepth(sub_key, variable):
    delmt = '__'
    for item in sub_key:
        try:
            if isinstance(sub_key[item], dict):
                sub_variable = variable + delmt + item
                checkdepth(sub_key[item], sub_variable)
        except TypeError:
            continue

        if isinstance(sub_key[item], list):
            sub_variable = variable + delmt + item
            for it in sub_key[item]:
                sub_variable = variable + delmt + item + delmt + str(sub_key[item].index(it))
                checkdepth(it, sub_variable)
            print(sub_variable)

        if isinstance(sub_key[item], int) or isinstance(sub_key[item], str):
                sub_variable = variable + delmt + item
                print (sub_variable)

for key in data:   
    if type(data[key]) is str:
       print(key + '=' +str(data[key]))
    else:
      variable = key
      checkdepth(data[key], variable)

I know that the problem in block where I process list data type, but I don't know where is the problem exactly我知道我处理列表数据类型的块中的问题,但我不知道问题到底出在哪里

Ok, I looked at your code and it's hard to follow.好的,我查看了您的代码,很难理解。 You're variable and function names are not easy to understand their purpose.您是可变的,并且 function 名称不容易理解它们的目的。 Which is fine cause everyone has to learn best practice and all the little tips and tricks in python.这很好,因为每个人都必须学习最佳实践以及 python 中的所有小技巧和窍门。 So hopefully I can help you out.所以希望我能帮助你。

  1. You have a recursive-ish function.你有一个递归式 function。 Which is definingly the best way to handle a situation like this.这无疑是处理这种情况的最佳方式。 However your code is part recursive and part not.但是,您的代码部分是递归的,部分不是。 If you go recursive to solve a problem you have to go 100% recursive.如果你用 go 递归来解决问题,你必须 go 100% 递归。

  2. Also the only time you should print in a recursive function is for debugging.此外,您应该在递归 function 中打印的唯一时间是用于调试。 Recursive functions should have an object that is passed down the function and gets appended to or altered and then passed back once it gets to the end of the recursion.递归函数应该有一个 object 向下传递 function 并被附加或更改,然后在到达递归结束时传回。

  3. When you get a problem like this, think about which data you actually need or care about.当您遇到此类问题时,请考虑您实际需要或关心哪些数据。 In this problem we don't care about the values that are stored in the object, we just care about the keys.在这个问题中,我们不关心存储在 object 中的值,我们只关心键。 So we should write code that doesn't even bother looking at the value of something except to determine its type.因此,我们应该编写的代码甚至不需要查看某个东西的值,而是确定它的类型。

Here is some code I wrote up that should work for what you're wanting to do.这是我编写的一些代码,它们应该适用于您想要做的事情。 But take note that because I did purely a recursive function my code base is small.但请注意,因为我做了纯粹的递归 function 我的代码库很小。 Also my function uses a list that is passed around and added to and then at the end I return it so that we can use it for whatever we need.此外,我的 function 使用了一个列表,该列表被传递并添加到最后我返回它,以便我们可以将它用于我们需要的任何东西。 If you have questions just comment on this question and I'll answer the best I can.如果您有任何问题,请对这个问题发表评论,我会尽我所能回答。

def convert_to_delimited_keys(obj, parent_key='', delimiter='__', keys_list=None):
    if keys_list is None: keys_list = []

    if isinstance(obj, dict):
        for k in obj:
            convert_to_delimited_keys(obj[k], delimiter.join((parent_key, str(k))), delimiter, keys_list)
    elif isinstance(obj, list):
        for i, _ in enumerate(obj):
            convert_to_delimited_keys(obj[i], delimiter.join((parent_key, str(i))), delimiter, keys_list)
    else:
        # Append to list, but remove the leading delimiter due to string.join
        keys_list.append(parent_key[len(delimiter):])
    return keys_list

for item in convert_to_delimited_keys(data):
    print(item)

Using json_flatten this can be converted to pandas, but it's not clear if that's what you want.使用 json_flatten 可以将其转换为 pandas,但不清楚这是否是您想要的。 Also, when you do convert it can use df.iloc[0] to see why each column is being provided (ie you see the value for that key).此外,当您进行转换时,可以使用 df.iloc[0] 查看为什么提供每列(即您看到该键的值)。

Note: you need to pass a list so I just wrapped your json above in [].注意:您需要传递一个列表,所以我只是将您的 json 包装在 [] 中。

# https://github.com/amirziai/flatten
dic = your json from above
dic =[dic] # put it in a list
dic_flattened = (flatten(d, '__') for d in dic) # add your delimiter
df = pd.DataFrame(dic_flattened)

df.iloc[0]

Logging__LogLevel__Default                                                                                    Information
Logging__LogLevel__Microsoft                                                                                      Warning
Logging__LogLevel__Microsoft.Hosting.Lifetime                                                                 Information
Logging__LogLevel__Microsoft.AspNetCore                                                                           Warning
Logging__LogLevel__System.Net.Http.HttpClient.Default.ClientHandler                                               Warning
Logging__LogLevel__System.Net.Http.HttpClient.Default.LogicalHandler                                              Warning
AllowedHosts                                                                                                            *
AutomaticTransferOptions__DateOffsetForDirectoriesInDays                                                               -1
AutomaticTransferOptions__DateOffsetForPortfoliosInDays                                                                -3
AutomaticTransferOptions__Clause__Item1                                                                                 1
Authentication__ApiKeys__0__Key                                                      AB8E5976-2A7C-4EEE-92C1-7B0B4DC840F6
Authentication__ApiKeys__0__OwnerName                                                                            Cron job
Authentication__ApiKeys__0__Claims__0__Type                             http://schemas.microsoft.com/ws/2008/06/identi...
Authentication__ApiKeys__0__Claims__0__Value                                                            StressTestManager
Authentication__ApiKeys__1__Key                                                      B11D4F27-483A-4234-8EC7-CA121712D5BE
Authentication__ApiKeys__1__OwnerName                                                                          Test admin
Authentication__ApiKeys__1__Claims__0__Type                             http://schemas.microsoft.com/ws/2008/06/identi...
Authentication__ApiKeys__1__Claims__0__Value                                                              StressTestAdmin
Authentication__ApiKeys__1__Claims__1__Type                             http://schemas.microsoft.com/ws/2008/06/identi...
Authentication__ApiKeys__1__Claims__1__Value                                                                  TestManager
Authentication__ApiKeys__2__Key                                                      EBF98F2E-555E-4E66-9D77-5667E0AA1B54
Authentication__ApiKeys__2__OwnerName                                                                        Test manager
Authentication__ApiKeys__2__Claims__0__Type                             http://schemas.microsoft.com/ws/2008/06/identi...
Authentication__ApiKeys__2__Claims__0__Value                                                                  TestManager
Authentication__LDAP__Domain                                                                                 domain.local
Authentication__LDAP__MachineAccountName                                                                           Soft13
Authentication__LDAP__MachineAccountPassword                                                                 vixuUEY7884*
Authentication__LDAP__EnableLdapClaimResolution                                                                      true
Authorization__Permissions__Roles__0__Role                                                                      TestAdmin
Authorization__Permissions__Roles__0__Permissions__0                                                     transfers.create
Authorization__Permissions__Roles__0__Permissions__1                                                      bindings.create
Authorization__Permissions__Roles__1__Role                                                                    TestManager
Authorization__Permissions__Roles__1__Permissions__0                                                     transfers.create

Use a recursive generator:使用递归生成器:

import json

with open('input.json') as f:
    data = json.load(f)

def strkeys(data):
    if isinstance(data,dict):
        for k,v in data.items():
            for item in strkeys(v):
                yield f'{k}__{item}' if item else k
    elif isinstance(data,list):
        for i,v in enumerate(data):
            for item in strkeys(v):
                yield f'{i}__{item}' if item else str(i)
    else:
        yield None # termination condition, not a list or dict

for s in strkeys(data):
    print(s)

Output: Output:

Logging__LogLevel__Default
Logging__LogLevel__Microsoft
Logging__LogLevel__Microsoft.Hosting.Lifetime
Logging__LogLevel__Microsoft.AspNetCore
Logging__LogLevel__System.Net.Http.HttpClient.Default.ClientHandler
Logging__LogLevel__System.Net.Http.HttpClient.Default.LogicalHandler
AllowedHosts
AutomaticTransferOptions__DateOffsetForDirectoriesInDays
AutomaticTransferOptions__DateOffsetForPortfoliosInDays
AutomaticTransferOptions__Clause__Item1
Authentication__ApiKeys__0__Key
Authentication__ApiKeys__0__OwnerName
Authentication__ApiKeys__0__Claims__0__Type
Authentication__ApiKeys__0__Claims__0__Value
Authentication__ApiKeys__1__Key
Authentication__ApiKeys__1__OwnerName
Authentication__ApiKeys__1__Claims__0__Type
Authentication__ApiKeys__1__Claims__0__Value
Authentication__ApiKeys__1__Claims__1__Type
Authentication__ApiKeys__1__Claims__1__Value
Authentication__ApiKeys__2__Key
Authentication__ApiKeys__2__OwnerName
Authentication__ApiKeys__2__Claims__0__Type
Authentication__ApiKeys__2__Claims__0__Value
Authentication__LDAP__Domain
Authentication__LDAP__MachineAccountName
Authentication__LDAP__MachineAccountPassword
Authentication__LDAP__EnableLdapClaimResolution
Authorization__Permissions__Roles__0__Role
Authorization__Permissions__Roles__0__Permissions__0
Authorization__Permissions__Roles__0__Permissions__1
Authorization__Permissions__Roles__1__Role
Authorization__Permissions__Roles__1__Permissions__0

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

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