Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Unmarshal daripada kunci JSON yang mengandungi petikan tunggal

Unmarshal daripada kunci JSON yang mengandungi petikan tunggal

WBOY
WBOYke hadapan
2024-02-14 15:12:09503semak imbas

从包含单引号的 JSON 键解组

editor php Shinichi memperkenalkan teknik yang menarik, iaitu unmarshal dari kunci JSON yang mengandungi petikan tunggal. Petua ini boleh membantu pembangun menjadi lebih fleksibel semasa memproses data JSON dan mengelakkan ralat penghuraian yang disebabkan oleh kemasukan petikan tunggal. Dengan menggunakan beberapa helah dan fungsi mudah, pembangun boleh mengendalikan situasi ini dengan mudah dan memastikan penghuraian dan pemprosesan data JSON yang betul. Teknik ini sangat berguna untuk pembangun yang sering berurusan dengan data JSON, dan boleh meningkatkan kecekapan pembangunan dan kualiti kod.

Kandungan soalan

Saya sangat keliru tentang perkara ini. Saya perlu memuatkan beberapa data bersiri dalam json (dari pangkalan data Perancis) di mana beberapa kunci mempunyai petikan tunggal.

Ini adalah versi ringkas:

package main

import (
    "encoding/json"
    "fmt"
)

type product struct {
    name string `json:"nom"`
    cost int64  `json:"prix d'achat"`
}

func main() {
    var p product
    err := json.unmarshal([]byte(`{"nom":"savon", "prix d'achat": 170}`), &p)
    fmt.printf("product cost: %d\nerror: %s\n", p.cost, err)
}

// product cost: 0
// error: %!s(<nil>)

Unmarshalling tidak menyebabkan ralat, tetapi "prix d'achat" (p.cost) tidak dihuraikan dengan betul.

Apabila saya menguraikan map[string]any kunci "prix d'achat" seperti yang saya jangkakan:

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    blob := map[string]any{}
    err := json.Unmarshal([]byte(`{"nom":"savon", "prix d'achat": 170}`), &blob)
    fmt.Printf("blob: %f\nerror: %s\n", blob["prix d'achat"], err)
}

// blob: 170.000000
// error: %!s(<nil>)

Saya menyemak dokumentasi json.marshal tentang penandaan struktur tetapi tidak menemui sebarang isu dengan data yang saya cuba proses.

Adakah saya kehilangan sesuatu yang jelas di sini? Bagaimana untuk menghuraikan kunci json yang mengandungi petikan tunggal menggunakan tag struct?

Terima kasih banyak atas pandangan anda!

Penyelesaian

Saya tidak menemui apa-apa dalam dokumentasi, tetapi pengekod json menganggap petikan tunggal sebagai aksara simpanan dalam nama tag.

func isvalidtag(s string) bool {
    if s == "" {
        return false
    }
    for _, c := range s {
        switch {
        case strings.containsrune("!#$%&()*+-./:;<=>?@[]^_{|}~ ", c):
            // backslash and quote chars are reserved, but
            // otherwise any punctuation chars are allowed
            // in a tag name.
        case !unicode.isletter(c) && !unicode.isdigit(c):
            return false
        }
    }
    return true
}

Saya fikir adalah munasabah untuk bertanya soalan di sini. Sementara itu, anda perlu melaksanakan json.unmarshaler dan/atau json.marshaler. Ini adalah permulaan:

func (p *Product) UnmarshalJSON(b []byte) error {
    type product Product // revent recursion
    var _p product

    if err := json.Unmarshal(b, &_p); err != nil {
        return err
    }

    *p = Product(_p)

    return unmarshalFieldsWithSingleQuotes(p, b)
}

func unmarshalFieldsWithSingleQuotes(dest interface{}, b []byte) error {
    // Look through the JSON tags. If there is one containing single quotes,
    // unmarshal b again, into a map this time. Then unmarshal the value
    // at the map key corresponding to the tag, if any.
    var m map[string]json.RawMessage

    t := reflect.TypeOf(dest).Elem()
    v := reflect.ValueOf(dest).Elem()

    for i := 0; i < t.NumField(); i++ {
        tag := t.Field(i).Tag.Get("json")
        if !strings.Contains(tag, "'") {
            continue
        }

        if m == nil {
            if err := json.Unmarshal(b, &m); err != nil {
                return err
            }
        }

        if j, ok := m[tag]; ok {
            if err := json.Unmarshal(j, v.Field(i).Addr().Interface()); err != nil {
                return err
            }
        }
    }

    return nil
}

Cuba di taman permainan: https://www.php.cn/link/9b47b8678d84ea8a0f9fe6c4ec599918一个>

Atas ialah kandungan terperinci Unmarshal daripada kunci JSON yang mengandungi petikan tunggal. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam
Artikel sebelumnya:Kenapa program ni hang?Artikel seterusnya:Kenapa program ni hang?