【问题标题】:Convert a nested key with values list to string value in JSON将带有值列表的嵌套键转换为 JSON 中的字符串值
【发布时间】:2021-01-01 22:17:34
【问题描述】:

我有一些非常嵌套的 JSON 文件。 使用 xmltodict 将其从 xml 转换为 JSON。

一些包含大量文本的值已放在一个列表中,但大多数情况下它们只是字符串。

所有文本值都在 ['P'] 值中。

我很好地找到了值列表的每个 ['P'] 并将它们转换为 sting。

if isinstance(t['DOFFIN_ESENDERS']['FORM_SECTION']['CONTRACT']['FD_CONTRACT']['LEFTI_CONTRACT']['F02_CONDITIONS_FOR_PARTICIPATION']['ECONOMIC_OPERATORS_PERSONAL_SITUATION']['P'], list):
            t['DOFFIN_ESENDERS']['FORM_SECTION']['CONTRACT']['FD_CONTRACT']['LEFTI_CONTRACT']['F02_CONDITIONS_FOR_PARTICIPATION']['ECONOMIC_OPERATORS_PERSONAL_SITUATION']['P'] = ' '.join([str(elem) for elem in t['DOFFIN_ESENDERS']['FORM_SECTION']['CONTRACT']['FD_CONTRACT']['LEFTI_CONTRACT']['F02_CONDITIONS_FOR_PARTICIPATION']['ECONOMIC_OPERATORS_PERSONAL_SITUATION']['P']])
        else:
            pass

这确实有效,但我必须编写 2000 行代码来更改每个值。 所以我在 JSON 文件上尝试了这个 object_hook 函数,但它没有做我擅长的事情。

def mydata_hook(obj):
    #obj_d = dict(obj)
    if obj['P'] in obj and isinstance(obj, list):
        obj['P'] =  str('P').strip('[]')
    else:
        return(obj)
        
    

path = 'C:/doffin/test/'

for filename in os.listdir(path):
    if not filename.endswith('.json'):
        continue
     
    
    fullname = os.path.join(path, filename)
    with open(fullname, 'rb') as f:
        jsonstr = f.read()

    json_sting = json.loads(jsonstr, object_hook=mydata_hook)
    json_str2 = json.dumps(json_sting)
    
    with open(fullname[:-4] + ".json", 'w') as f:
        f.write(json_str2)

编辑: 其中一个文件如下所示。

{
    "DOFFIN_ESENDERS": {
        "VERSION": "V3.0.2",
        "http://www.w3.org/2001/XMLSchema-instance:noNamespaceSchemaLocation": "DOFFIN_ESENDERS.xd",
        "xmlns": {
            "xsi": "http://www.w3.org/2001/XMLSchema-instance"
        },
        "FORM_SECTION": {
            "F52_2014": {
                "LG": "NB",
                "CATEGORY": "ORIGINAL",
                "FORM": "F52",
                "CONTRACTING_BODY": {
                    "ADDRESS_CONTRACTING_BODY": {
                        "OFFICIALNAME": "Halden Kommune",
                        "NATIONALID": "959159092",
                        "ADDRESS": "Storgata 8",
                        "TOWN": "HALDEN",
                        "POSTAL_CODE": "1751",
                        "COUNTRY": {
                            "VALUE": "NO"
                        },
                        "CONTACT_POINT": "Svein Andersen",
                        "PHONE": "+47 69174500",
                        "E_MAIL": "svein.andersen@halden.kommune.no",
                        "LOCATION": {
                            "code": "000000"
                        },
                        "URL_GENERAL": "https://permalink.mercell.com/128099026.aspx",
                        "URL_BUYER": "http://www.halden.kommune.no/"
                    },
                    "DOCUMENT_FULL": null,
                    "URL_DOCUMENT": "https://permalink.mercell.com/128099026.aspx",
                    "ADDRESS_FURTHER_INFO_IDEM": null,
                    "URL_PARTICIPATION": "https://permalink.mercell.com/128099026.aspx"
                },
                "OBJECT_CONTRACT": {
                    "TITLE": {
                        "P": "Forvaltning og utbygging av fiberinfrastruktur i Halden Kommune"
                    },
                    "REFERENCE_NUMBER": "2020/2088",
                    "CPV_MAIN": {
                        "CPV_CODE": {
                            "CODE": "64214400"
                        }
                    },
                    "TYPE_CONTRACT": {
                        "CTYPE": "SERVICES"
                    },
                    "SHORT_DESCR": {
                        "P": ["Halden kommune inviterer til \u00e5pen anbudskonkurranse for forvaltning og utbygging av fiberinfrastruktur i Halden Kommune.", "De siste \u00e5rene har Halden kommune investert i fiberinfrastruktur i kommunen parallelt med oppgradering av vann- og avl\u00f8psutbedringer. \u00a0I \u00e5rene som kommer har kommunen en m\u00e5lsetting om \u00f8kt utbygging av fiberinfrastruktur til offentlige bygg, n\u00e6ringsbygg og privatpersoner i Halden.", "Kommunen \u00f8nsker derfor \u00e5 legge best mulig til rette for utbygging ved \u00e5 innlede samarbeid med en virksomhet som kan ivareta kommunens, n\u00e6ringslivets og privatpersoners interesser best mulig.", "Kommunen \u00f8nsker samtidig \u00e5 redusere kommunens kostnader knyttet til fibertjenester inn til offentlige bygg."]
                    },
                    "NO_LOT_DIVISION": null,
                    "OBJECT_DESCR": {
                        "ITEM": "1",
                        "CPV_ADDITIONAL": {
                            "CPV_CODE": {
                                "CODE": "45232300"
                            }
                        },
                        "LOCATION": {
                            "code": "030101"
                        },
                        "SHORT_DESCR": {
                            "P": ["Gjennom anskaffelsen \u00f8nsker Halden kommune \u00e5 kunne levere tjenester til sine interne og eksterne kunder p\u00e5 en bedre m\u00e5te. Form\u00e5let med denne anskaffelsen er \u00e5 inng\u00e5 avtale med en leverand\u00f8r som kan ivareta f\u00f8lgende arbeider for kommunen:", "1. \u00a0 Videreleie/ selge kapasitet p\u00e5 kommunens eksisterende fibernett.", "2. \u00a0 Bygge ut og leie/ selge fiberkapasitet i kommunens tilgjengelige trekker\u00f8r.", "3. \u00a0 Informere akt\u00f8rer om gr\u00f8fter som graves i forbindelse med vedlikehold av kommunens vann- og avl\u00f8ps-", "nett.", "4. \u00a0 Administrere og drifte fibernettverket og dokumentere fremtidig infrastruktur.", "5. \u00a0 Bist\u00e5 med utarbeidelse av s\u00f8knader om midler til utbygging av fiber", "Denne anskaffelsen f\u00f8lger prosedyre for \u00e5pen anbudskonkurranse med bruk av hasteprosedyre. Hensyntatt den spesielle situasjonen rundt korona-utbrudd og viktigheten av informasjon ut til alle innbyggere settes det i gang med denne anskaffelsen. Anskaffelsen foretas innenfor et omr\u00e5de som defineres som samfunnskritisk infrastruktur hvor kommunen har et s\u00e6rlig ansvar for \u00e5 bidra til at det foretas videre utvikling og utbygging.", "Anskaffelsen innehar to konkrete utbyggingsprosjekter og i tillegg en forvaltning og utbyggingsdel for kommunen."]
                        },
                        "AC_PROCUREMENT_DOC": null,
                        "DURATION": {
                            "TYPE": "MONTH",
                            "text": "24"
                        }
                    }
                },
                "LEFTI": {
                    "QUALIFICATION_CRITERIA_DOC": null
                },
                "PROCEDURE": {
                    "PT_OPEN": null,
                    "OTHER_INFORMATION": {
                        "P": "Denne anskaffelsen f\u00f8lger prosedyre for \u00e5pen tilbudskonkurranse med bruk av hasteprosedyre. Hensyntatt den spesielle situasjonen rundt korona-utbrudd og viktigheten av informasjon ut til alle innbyggere settes det i gang med denne anskaffelsen. Anskaffelsen foretas innenfor et omr\u00e5de som defineres som samfunnskritisk infrastruktur hvor kommunen har et s\u00e6rlig ansvar for \u00e5 bidra til at det foretas videre utvikling og utbygging."
                    },
                    "DATE_RECEIPT_TENDERS": "2020-05-08",
                    "TIME_RECEIPT_TENDERS": "15:00",
                    "LANGUAGES": {
                        "LANGUAGE": {
                            "VALUE": "NO"
                        }
                    }
                },
                "COMPLEMENTARY_INFO": {
                    "DATE_DISPATCH_NOTICE": "2020-04-22"
                }
            }
        },
        "DOFFIN_APPENDIX": null
    }
}

一些“P”键是第 50 行的列表

"SHORT_DESCR": {
                        "P": ["Halden kommune

在第 64 行

"SHORT_DESCR": {
                            "P": ["Gjennom anskaffelsen

在第 80 行,它是一个字符串

"OTHER_INFORMATION": {
                        "P": "Denne anskaffelsen

【问题讨论】:

    标签: python json python-3.x


    【解决方案1】:

    据我了解,如果字符串列表包含在键值为“P”的(可能是嵌套的)字典中,则您希望在 json 中加入字符串列表。这似乎是递归的完美工作:

    import glob
    import json
    
    def process_json(obj):
        if isinstance(obj, dict):
            if "P" in obj and isinstance(obj["P"], list):
                obj["P"] = " ".join([str(e) for e in obj["P"]])
            for element in obj.values():
                mydata_hook(element)
    
    for path in glob.glob("C:/doffin/test/*.json"):
        with open(path) as fi:
            data = process_json(json.load(fi))
        
        with open(SOME_OUTPUT_PATH, "w") as fo:
            json.dump(data, fo)
    

    【讨论】:

    • 您好,我确实尝试过您的代码,但它不起作用。对于 obj.values() 中的元素:mydata_hook(element) mydata_hook 现在是什么? golb.glob 不采用“C:/PATH”,因此 path = “C:/doffin281220/test/”和 glob.glob 中的路径(path + '\*.json'):我确实用以下之一更新了我的帖子文件。
    【解决方案2】:

    我确实找到了另一篇文章来处理这个问题并更改了代码并添加了您的部分代码。 另一个帖子是Iterate over all items in json object

    有效的升级代码是

    def recursive_iter(obj):
        if isinstance(obj, dict):
            for item in obj.values():
                if "P" in obj and isinstance(obj["P"], list):
                    obj["P"] = " ".join([str(e) for e in obj["P"]])
                else:
                    yield from recursive_iter(item)
        elif any(isinstance(obj, t) for t in (list, tuple)):
            for item in obj:
                yield from recursive_iter(item)
        else:
            yield obj
    
    path = "C:/doffin281220/test/"
    
    for filename in os.listdir(path):
        if not filename.endswith('.json'):
            continue
         
        
        fullname = os.path.join(path, filename)
        with open(fullname, 'rb') as f:
            jsonstr = f.read()
    
        json_sting = json.loads(jsonstr)
        for item in recursive_iter(json_sting):
            json_str2 = json.dumps(json_sting)
        
        with open(fullname[:-4] + ".json", 'w') as f:
            f.write(json_str2)
    

    这会读取文件夹中的所有 JSON 文件并使用相同的文件名 +..json 保存新更新的文件

    我在组织中的文件。帖子现在看起来像这样。

    {
        "DOFFIN_ESENDERS": {
            "VERSION": "V3.0.2",
            "http://www.w3.org/2001/XMLSchema-instance:noNamespaceSchemaLocation": "DOFFIN_ESENDERS.xd",
            "xmlns": {
                "xsi": "http://www.w3.org/2001/XMLSchema-instance"
            },
            "FORM_SECTION": {
                "F52_2014": {
                    "LG": "NB",
                    "CATEGORY": "ORIGINAL",
                    "FORM": "F52",
                    "CONTRACTING_BODY": {
                        "ADDRESS_CONTRACTING_BODY": {
                            "OFFICIALNAME": "Halden Kommune",
                            "NATIONALID": "959159092",
                            "ADDRESS": "Storgata 8",
                            "TOWN": "HALDEN",
                            "POSTAL_CODE": "1751",
                            "COUNTRY": {
                                "VALUE": "NO"
                            },
                            "CONTACT_POINT": "Svein Andersen",
                            "PHONE": "+47 69174500",
                            "E_MAIL": "svein.andersen@halden.kommune.no",
                            "LOCATION": {
                                "code": "000000"
                            },
                            "URL_GENERAL": "https://permalink.mercell.com/128099026.aspx",
                            "URL_BUYER": "http://www.halden.kommune.no/"
                        },
                        "DOCUMENT_FULL": null,
                        "URL_DOCUMENT": "https://permalink.mercell.com/128099026.aspx",
                        "ADDRESS_FURTHER_INFO_IDEM": null,
                        "URL_PARTICIPATION": "https://permalink.mercell.com/128099026.aspx"
                    },
                    "OBJECT_CONTRACT": {
                        "TITLE": {
                            "P": "Forvaltning og utbygging av fiberinfrastruktur i Halden Kommune"
                        },
                        "REFERENCE_NUMBER": "2020/2088",
                        "CPV_MAIN": {
                            "CPV_CODE": {
                                "CODE": "64214400"
                            }
                        },
                        "TYPE_CONTRACT": {
                            "CTYPE": "SERVICES"
                        },
                        "SHORT_DESCR": {
                            "P": "Halden kommune inviterer til \u00e5pen anbudskonkurranse for forvaltning og utbygging av fiberinfrastruktur i Halden Kommune. De siste \u00e5rene har Halden kommune investert i fiberinfrastruktur i kommunen parallelt med oppgradering av vann- og avl\u00f8psutbedringer. \u00a0I \u00e5rene som kommer har kommunen en m\u00e5lsetting om \u00f8kt utbygging av fiberinfrastruktur til offentlige bygg, n\u00e6ringsbygg og privatpersoner i Halden. Kommunen \u00f8nsker derfor \u00e5 legge best mulig til rette for utbygging ved \u00e5 innlede samarbeid med en virksomhet som kan ivareta kommunens, n\u00e6ringslivets og privatpersoners interesser best mulig. Kommunen \u00f8nsker samtidig \u00e5 redusere kommunens kostnader knyttet til fibertjenester inn til offentlige bygg."
                        },
                        "NO_LOT_DIVISION": null,
                        "OBJECT_DESCR": {
                            "ITEM": "1",
                            "CPV_ADDITIONAL": {
                                "CPV_CODE": {
                                    "CODE": "45232300"
                                }
                            },
                            "LOCATION": {
                                "code": "030101"
                            },
                            "SHORT_DESCR": {
                                "P": "Gjennom anskaffelsen \u00f8nsker Halden kommune \u00e5 kunne levere tjenester til sine interne og eksterne kunder p\u00e5 en bedre m\u00e5te. Form\u00e5let med denne anskaffelsen er \u00e5 inng\u00e5 avtale med en leverand\u00f8r som kan ivareta f\u00f8lgende arbeider for kommunen: 1. \u00a0 Videreleie/ selge kapasitet p\u00e5 kommunens eksisterende fibernett. 2. \u00a0 Bygge ut og leie/ selge fiberkapasitet i kommunens tilgjengelige trekker\u00f8r. 3. \u00a0 Informere akt\u00f8rer om gr\u00f8fter som graves i forbindelse med vedlikehold av kommunens vann- og avl\u00f8ps- nett. 4. \u00a0 Administrere og drifte fibernettverket og dokumentere fremtidig infrastruktur. 5. \u00a0 Bist\u00e5 med utarbeidelse av s\u00f8knader om midler til utbygging av fiber Denne anskaffelsen f\u00f8lger prosedyre for \u00e5pen anbudskonkurranse med bruk av hasteprosedyre. Hensyntatt den spesielle situasjonen rundt korona-utbrudd og viktigheten av informasjon ut til alle innbyggere settes det i gang med denne anskaffelsen. Anskaffelsen foretas innenfor et omr\u00e5de som defineres som samfunnskritisk infrastruktur hvor kommunen har et s\u00e6rlig ansvar for \u00e5 bidra til at det foretas videre utvikling og utbygging. Anskaffelsen innehar to konkrete utbyggingsprosjekter og i tillegg en forvaltning og utbyggingsdel for kommunen."
                            },
                            "AC_PROCUREMENT_DOC": null,
                            "DURATION": {
                                "TYPE": "MONTH",
                                "text": "24"
                            }
                        }
                    },
                    "LEFTI": {
                        "QUALIFICATION_CRITERIA_DOC": null
                    },
                    "PROCEDURE": {
                        "PT_OPEN": null,
                        "OTHER_INFORMATION": {
                            "P": "Denne anskaffelsen f\u00f8lger prosedyre for \u00e5pen tilbudskonkurranse med bruk av hasteprosedyre. Hensyntatt den spesielle situasjonen rundt korona-utbrudd og viktigheten av informasjon ut til alle innbyggere settes det i gang med denne anskaffelsen. Anskaffelsen foretas innenfor et omr\u00e5de som defineres som samfunnskritisk infrastruktur hvor kommunen har et s\u00e6rlig ansvar for \u00e5 bidra til at det foretas videre utvikling og utbygging."
                        },
                        "DATE_RECEIPT_TENDERS": "2020-05-08",
                        "TIME_RECEIPT_TENDERS": "15:00",
                        "LANGUAGES": {
                            "LANGUAGE": {
                                "VALUE": "NO"
                            }
                        }
                    },
                    "COMPLEMENTARY_INFO": {
                        "DATE_DISPATCH_NOTICE": "2020-04-22"
                    }
                }
            },
            "DOFFIN_APPENDIX": null
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-06-04
      • 2016-02-08
      • 2012-01-28
      • 2020-05-13
      • 2021-11-25
      • 2020-06-05
      • 1970-01-01
      • 2019-04-24
      • 1970-01-01
      相关资源
      最近更新 更多