将带值列表的嵌套键转换为JSON中的字符串值

2024-09-29 01:23:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一些非常嵌套的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

Tags: jsonobjformednullogcontractav
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
    }
}

根据我的理解,如果字符串包含在键值为“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)

相关问题 更多 >