Unmarshal daripada kunci JSON yang mengandungi petikan tunggal

WBOY
Lepaskan: 2024-02-14 15:12:09
ke hadapan
561 orang telah melayarinya

从包含单引号的 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>)
Salin selepas log masuk

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>)
Salin selepas log masuk

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
}
Salin selepas log masuk

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
}
Salin selepas log masuk

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!

sumber:stackoverflow.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan