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

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

php小编草莓介绍:YAML是一种轻量级的数据序列化格式,它具有简洁易读的语法,被广泛用于配置文件和数据交换。在PHP中,我们可以使用YAML解析库将YAML数据解组为复杂对象,这些对象可以是结构体或字符串。这为开发人员提供了一种方便的方式来处理和操作配置文件和其他数据。无论是构建复杂的应用程序还是简化配置管理,YAML解析在PHP中发挥着重要的作用。

问题内容

尝试将 yaml 解组为复杂对象,例如 map[string]map[interface{}]string。问题是我希望能够区分 string 和 source 之间的 interface{} 部分,这是一个结构。

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"`}

登录后复制

显然 yaml 不知道如何解组到 source 结构中,所以我必须实现 unmarshaler 接口:

type unmarshaler interface {    unmarshalyaml(value *node) error}

登录后复制

但我不太了解解组过程的总体情况。一般来说,我假设我必须手动遍历 *yaml.node 并在每个节点上调用 func unmarshalyaml(value *node) error 。

package mainimport (    "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}

登录后复制

去游乐场

解决方法

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"`}

登录后复制

https://www.php.cn/link/50f9999b2ee27e222c5513e945e9ea9c

如果您需要保持映射类型不变,即不添加自定义键类型,那么您也可以在 unft 上实现解组器,只需使用 any 进行重新映射即可:

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}

登录后复制

https://www.php.cn/link/543378fb36a83810ded2d725f2b6c883

以上就是将 YAML 解组为复杂对象,可以是结构体或字符串的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2358193.html

(0)
上一篇 2025年3月1日 16:52:34
下一篇 2025年3月1日 16:52:49

AD推荐 黄金广告位招租... 更多推荐

相关推荐

发表回复

登录后才能评论