Entpacken Sie YAML in komplexe Objekte, entweder Strukturen oder Strings

WBOY
Freigeben: 2024-02-09 08:48:29
nach vorne
886 Leute haben es durchsucht

将 YAML 解组为复杂对象,可以是结构体或字符串

PHP Editor Strawberry Einführung: YAML ist ein leichtes Datenserialisierungsformat. Es verfügt über eine prägnante und leicht lesbare Syntax und wird häufig für Konfigurationsdateien und den Datenaustausch verwendet. In PHP können wir die YAML-Parsing-Bibliothek verwenden, um YAML-Daten in komplexe Objekte zu entpacken, bei denen es sich um Strukturen oder Strings handeln kann. Dies bietet Entwicklern eine bequeme Möglichkeit, Konfigurationsdateien und andere Daten zu verwalten und zu bearbeiten. Unabhängig davon, ob Sie komplexe Anwendungen erstellen oder das Konfigurationsmanagement vereinfachen, spielt das YAML-Parsing in PHP eine wichtige Rolle.

Frageninhalt

Versuchen Sie, Yaml in komplexe Objekte wie map[string]map[interface{}]string zu zerlegen. Das Problem ist, dass ich den stringsource 之间的 interface{}-Teil unterscheiden möchte, der eine Struktur ist.

type source struct {
    id     string `yaml:"id"`
    name   string `yaml:"name"`
    logoid string `yaml:"logoid"`
    url    string `yaml:"url"`
}

type unft struct {
    itemmeta map[string]map[interface{}]string `yaml:"item_meta"`
    // could be
    // itemmeta map[string]map[string]string `yaml:"item_meta"`
    // or
    // itemmeta map[string]map[source]string `yaml:"item_meta"`
}
Nach dem Login kopieren

Anscheinend weiß das Yaml nicht, wie man es in die source 结构中,所以我必须实现 unmarshaler-Schnittstelle entmarshallt:

type unmarshaler interface {
    unmarshalyaml(value *node) error
}
Nach dem Login kopieren

Aber ich verstehe die Gesamtsituation des Unmarshalling-Prozesses nicht ganz. Im Allgemeinen gehe ich davon aus, dass ich *yaml.node 并在每个节点上调用 func unmarshalyaml(value *node) error manuell durchlaufen muss.

package main

import (
    "fmt"

    "gopkg.in/yaml.v3"
)

type Source struct {
    ID     string `json:"id"`
    Name   string `json:"name"`
    LogoID string `json:"logoId"`
    URL    string `json:"url"`
}

var data = `
unf:
    item_meta:
      source:
           !struct
           ? id: "data-watch" 
             name: "DataWatch"
             logoid: "data-watch"
             url: "https"
           : "product_any('SS')"
      public_usage:
        "": "source_any('SDF')"
        "provider": "source_any('ANO')"`

type UNFT struct {
    ItemMeta map[string]map[interface{}]string `yaml:"item_meta"`
}

type MetaConverterConfigT struct {
    UNFT UNFT `yaml:"unf"`
}

func main() {
    cfg := MetaConverterConfigT{}

    err := yaml.Unmarshal([]byte(data), &cfg)
    if err != nil {
        fmt.Println("%w", err)
    }

    fmt.Println(cfg)
}

func (s *UNFT) UnmarshalYAML(n *yaml.Node) error {
    var cfg map[string]map[interface{}]string
    if err := n.Decode(&cfg); err != nil {
        fmt.Println("%w", err)
    }

    return nil
}
Nach dem Login kopieren

Gehen Sie in den Vergnügungspark

Lösung

type metakey struct {
    string string
    source source
}

func (k *metakey) unmarshalyaml(n *yaml.node) error {
    if n.tag == "!!str" {
        return n.decode(&k.string)
    }
    if n.tag == "!!map" {
        return n.decode(&k.source)
    }
    return fmt.errorf("unsupported metakey type")
}

// ...

type unft struct {
    itemmeta map[string]map[metakey]string `yaml:"item_meta"`
}
Nach dem Login kopieren

//m.sbmmt.com/link/50f9999b2ee27e222c5513e945e9ea9c

Wenn Sie den zugeordneten Typ unverändert lassen müssen, d. h. ohne einen benutzerdefinierten Schlüsseltyp hinzuzufügen, können Sie den Unmarshaller auch auf unft implementieren und ihn einfach mit any:

neu zuordnen
type UNFT struct {
    ItemMeta map[string]map[any]string `yaml:"item_meta"`
}

func (u *UNFT) UnmarshalYAML(n *yaml.Node) error {
    var obj struct {
        ItemMeta map[string]map[MetaKey]string `yaml:"item_meta"`
    }
    if err := n.Decode(&obj); err != nil {
        return err
    }

    u.ItemMeta = make(map[string]map[any]string, len(obj.ItemMeta))
    for k, v := range obj.ItemMeta {
        m := make(map[any]string, len(v))
        for k, v := range v {
            if k.Source != (Source{}) {
                m[k.Source] = v
            } else {
                m[k.String] = v
            }
        }
        u.ItemMeta[k] = m
    }
    return nil
}
Nach dem Login kopieren

//m.sbmmt.com/link/543378fb36a83810ded2d725f2b6c883

Das obige ist der detaillierte Inhalt vonEntpacken Sie YAML in komplexe Objekte, entweder Strukturen oder Strings. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!