如何解析复杂嵌套的 YAML 数据结构?

huangapple go评论75阅读模式
英文:

How do I Unmarshal complex nesting of yaml

问题

如何解组这个数据?我试图提取名称、描述、版本和其他字段。但是当我打印出解组后的内容时,我得到以下结果:

Index: {ApiVersion:v1 Entry:map[]
Generated:2016-10-06T16:23:20.499029981-06:00}

以下是我到目前为止尝试过的方法。

package main

import (
    "fmt"
    "log"

    "gopkg.in/yaml.v2"
)

const index_yaml = `apiVersion: v1
entries:
    alpine:
    - created: 2016-10-06T16:23:20.499814565-06:00
        description: Deploy a basic Alpine Linux pod
        digest: 99c76e403d752c84ead610644d4b1c2f2b453a74b921f422b9dcb8a7c8b559cd
        home: https://helm.sh/helm
        name: alpine
        sources:
        - https://github.com/helm/helm
        urls:
        - https://technosophos.github.io/tscharts/alpine-0.2.0.tgz
        version: 0.2.0
    - created: 2016-10-06T16:23:20.499543808-06:00
        description: Deploy a basic Alpine Linux pod
        digest: 515c58e5f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cd78727
        home: https://helm.sh/helm
        name: alpine
        sources:
        - https://github.com/helm/helm
        urls:
        - https://technosophos.github.io/tscharts/alpine-0.1.0.tgz
        version: 0.1.0
    nginx:
    - created: 2016-10-06T16:23:20.499543808-06:00
        description: Create a basic nginx HTTP server
        digest: aaff4545f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cdffffff
        home: https://helm.sh/helm
        name: nginx
        sources:
        - https://github.com/helm/charts
        urls:
        - https://technosophos.github.io/tscharts/nginx-1.1.0.tgz
        version: 1.1.0
generated: 2016-10-06T16:23:20.499029981-06:00`

type Entry struct {
    Created     string `yaml:"created"`
    Description string `yaml:"description"`
    Home        string `yaml:"home"`
}

type Entries map[string][]Entry

type Index struct {
    ApiVersion string  `yaml:"apiVersion"`
    Entry      Entries `yaml:"entries"`
    Generated  string  `yaml:"generated"`
}

func main() {
    // data, err := ioutil.ReadFile("index.yaml")
    // if err != nil {
    // 	log.Fatal("Error reading index", err)
    // 	return
    // }

    var index Index
    err := yaml.Unmarshal([]byte(index_yaml), &index)
    if err != nil {
        log.Fatal("File reading error", err)
        return
    }

    fmt.Printf("Index: %+v", index)
}
英文:

How do I unmarshal this data? I'm trying to extract the Name, Description, Version and other fields. But when I print out the unmarshaled content I get the following:

> Index: {ApiVersion:v1 Entry:map[]
> Generated:2016-10-06T16:23:20.499029981-06:00}

Here is what I've tried so far.

package main

import (
    "fmt"
    "log"

    "gopkg.in/yaml.v2"
)

const index_yaml = `apiVersion: v1
entries:
    alpine:
    - created: 2016-10-06T16:23:20.499814565-06:00
        description: Deploy a basic Alpine Linux pod
        digest: 99c76e403d752c84ead610644d4b1c2f2b453a74b921f422b9dcb8a7c8b559cd
        home: https://helm.sh/helm
        name: alpine
        sources:
        - https://github.com/helm/helm
        urls:
        - https://technosophos.github.io/tscharts/alpine-0.2.0.tgz
        version: 0.2.0
    - created: 2016-10-06T16:23:20.499543808-06:00
        description: Deploy a basic Alpine Linux pod
        digest: 515c58e5f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cd78727
        home: https://helm.sh/helm
        name: alpine
        sources:
        - https://github.com/helm/helm
        urls:
        - https://technosophos.github.io/tscharts/alpine-0.1.0.tgz
        version: 0.1.0
    nginx:
    - created: 2016-10-06T16:23:20.499543808-06:00
        description: Create a basic nginx HTTP server
        digest: aaff4545f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cdffffff
        home: https://helm.sh/helm
        name: nginx
        sources:
        - https://github.com/helm/charts
        urls:
        - https://technosophos.github.io/tscharts/nginx-1.1.0.tgz
        version: 1.1.0
generated: 2016-10-06T16:23:20.499029981-06:00`

type Entry struct {
    Created     string `yaml:"created"`
    Description string `yaml:"created"`
    Home        string `yaml:"home"`
}

type Entries map[string][]Entry

type Index struct {
    ApiVersion string  `yaml:"apiVersion"`
    Entry      Entries `yaml:"entry"`
    Generated  string  `yaml:"generated"`
}

func main() {
    // data, err := ioutil.ReadFile("index.yaml")
    // if err != nil {
    // 	log.Fatal("Error reading index", err)
    // 	return
    // }

    var index Index
    err := yaml.Unmarshal([]byte(index_yaml), &index)
    if err != nil {
        log.Fatal("File reading error", err)
        return
    }

    fmt.Printf("Index: %+v", index)
}

答案1

得分: 1

这是一个很棒的服务,你可以使用它来为你的YAML文件生成结构体。以下是它的工作结果。

type AutoGenerated struct {
    APIVersion string `yaml:"apiVersion"`
    Entries    struct {
        Alpine []struct {
            Created     struct{} `yaml:"created"`
            Description string   `yaml:"description"`
            Digest      string   `yaml:"digest"`
            Home        string   `yaml:"home"`
            Name        string   `yaml:"name"`
            Sources     []string `yaml:"sources"`
            Urls        []string `yaml:"urls"`
            Version     string   `yaml:"version"`
        } `yaml:"alpine"`
        Nginx []struct {
            Created     struct{} `yaml:"created"`
            Description string   `yaml:"description"`
            Digest      string   `yaml:"digest"`
            Home        string   `yaml:"home"`
            Name        string   `yaml:"name"`
            Sources     []string `yaml:"sources"`
            Urls        []string `yaml:"urls"`
            Version     string   `yaml:"version"`
        } `yaml:"nginx"`
    } `yaml:"entries"`
    Generated struct{} `yaml:"generated"`
}

var doc AutoGenerated
err := yaml.Unmarshal([]byte(index_yaml), &doc)
if err != nil {
    log.Fatalf("error: %v", err)
    return
}

fmt.Printf("Doc: %+v", doc)

你可以在需要的地方添加omitempty,或者根据需要更改结构。

更新:

package main

import (
	"fmt"
	"log"

	"gopkg.in/yaml.v2"
)

type Entry struct {
	Created     string   `yaml:"created"`
	Description string   `yaml:"description"`
	Digest      string   `yaml:"digest"`
	Home        string   `yaml:"home"`
	Name        string   `yaml:"name"`
	Sources     []string `yaml:"sources"`
	Urls        []string `yaml:"urls"`
	Version     string   `yaml:"version"`
}

type AutoGenerated struct {
	APIVersion string             `yaml:"apiVersion"`
	Entries    map[string][]Entry `yaml:"entries"`
	Generated  string             `yaml:"generated"`
}

func main() {

	var doc AutoGenerated
	err := yaml.Unmarshal([]byte(index_yaml), &doc)
	if err != nil {
		log.Fatalf("error: %v", err)
		return
	}

	fmt.Printf("Doc: %+v", doc)

}

const index_yaml = `apiVersion: v1
entries:
  alpine:
    - created: 2016-10-06T16:23:20.499814565-06:00
      description: Deploy a basic Alpine Linux pod
      digest: 99c76e403d752c84ead610644d4b1c2f2b453a74b921f422b9dcb8a7c8b559cd
      home: https://helm.sh/helm
      name: alpine
      sources:
      - https://github.com/helm/helm
      urls:
      - https://technosophos.github.io/tscharts/alpine-0.2.0.tgz
      version: 0.2.0
    - created: 2016-10-06T16:23:20.499543808-06:00
      description: Deploy a basic Alpine Linux pod
      digest: 515c58e5f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cd78727
      home: https://helm.sh/helm
      name: alpine
      sources:
      - https://github.com/helm/helm
      urls:
      - https://technosophos.github.io/tscharts/alpine-0.1.0.tgz
      version: 0.1.0
  nginx:
    - created: 2016-10-06T16:23:20.499543808-06:00
      description: Create a basic nginx HTTP server
      digest: aaff4545f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cdffffff
      home: https://helm.sh/helm
      name: nginx
      sources:
      - https://github.com/helm/charts
      urls:
      - https://technosophos.github.io/tscharts/nginx-1.1.0.tgz
      version: 1.1.0
generated: 2016-10-06T16:23:20.499029981-06:00`
英文:

Here is wonderfull service you can use to make struct for your yamls. This is result of its work.

    type AutoGenerated struct {
        APIVersion string `yaml:"apiVersion"`
        Entries    struct {
            Alpine []struct {
                Created struct {
                } `yaml:"created"`
                Description string   `yaml:"description"`
                Digest      string   `yaml:"digest"`
                Home        string   `yaml:"home"`
                Name        string   `yaml:"name"`
                Sources     []string `yaml:"sources"`
                Urls        []string `yaml:"urls"`
                Version     string   `yaml:"version"`
            } `yaml:"alpine"`
            Nginx []struct {
                Created struct {
                } `yaml:"created"`
                Description string   `yaml:"description"`
                Digest      string   `yaml:"digest"`
                Home        string   `yaml:"home"`
                Name        string   `yaml:"name"`
                Sources     []string `yaml:"sources"`
                Urls        []string `yaml:"urls"`
                Version     string   `yaml:"version"`
            } `yaml:"nginx"`
        } `yaml:"entries"`
        Generated struct {
        } `yaml:"generated"`
    }

    var doc AutoGenerated
    err := yaml.Unmarshal([]byte(index_yaml), &doc)
    if err != nil {
        log.Fatalf("error: %v", err)
        return
    }

    fmt.Printf("Doc: %+v", doc)

you can add omitempty where you need it, or change structure as you want it.

update:

package main

import (
	"fmt"
	"log"

	"gopkg.in/yaml.v2"
)

type Entry struct {
	Created     string   `yaml:"created"`
	Description string   `yaml:"description"`
	Digest      string   `yaml:"digest"`
	Home        string   `yaml:"home"`
	Name        string   `yaml:"name"`
	Sources     []string `yaml:"sources"`
	Urls        []string `yaml:"urls"`
	Version     string   `yaml:"version"`
}

type AutoGenerated struct {
	APIVersion string             `yaml:"apiVersion"`
	Entries    map[string][]Entry `yaml:"entries"`
	Generated  string             `yaml:"generated"`
}

func main() {

	var doc AutoGenerated
	err := yaml.Unmarshal([]byte(index_yaml), &doc)
	if err != nil {
		log.Fatalf("error: %v", err)
		return
	}

	fmt.Printf("Doc: %+v", doc)

}

const index_yaml = `apiVersion: v1
entries:
  alpine:
    - created: 2016-10-06T16:23:20.499814565-06:00
      description: Deploy a basic Alpine Linux pod
      digest: 99c76e403d752c84ead610644d4b1c2f2b453a74b921f422b9dcb8a7c8b559cd
      home: https://helm.sh/helm
      name: alpine
      sources:
      - https://github.com/helm/helm
      urls:
      - https://technosophos.github.io/tscharts/alpine-0.2.0.tgz
      version: 0.2.0
    - created: 2016-10-06T16:23:20.499543808-06:00
      description: Deploy a basic Alpine Linux pod
      digest: 515c58e5f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cd78727
      home: https://helm.sh/helm
      name: alpine
      sources:
      - https://github.com/helm/helm
      urls:
      - https://technosophos.github.io/tscharts/alpine-0.1.0.tgz
      version: 0.1.0
  nginx:
    - created: 2016-10-06T16:23:20.499543808-06:00
      description: Create a basic nginx HTTP server
      digest: aaff4545f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cdffffff
      home: https://helm.sh/helm
      name: nginx
      sources:
      - https://github.com/helm/charts
      urls:
      - https://technosophos.github.io/tscharts/nginx-1.1.0.tgz
      version: 1.1.0
generated: 2016-10-06T16:23:20.499029981-06:00`

答案2

得分: 0

首先,您需要修改您的yaml输入的缩进,然后根据建议将Entry Entriesyaml:"entry"修改为yaml:"entries"

package main

import (
	"fmt"
	"log"

	"gopkg.in/yaml.v2"
)

const index_yaml = `apiVersion: v1
entries:
  alpine:
    - created: 2016-10-06T16:23:20.499814565-06:00
      description: Deploy a basic Alpine Linux pod
      digest: 99c76e403d752c84ead610644d4b1c2f2b453a74b921f422b9dcb8a7c8b559cd
      home: https://helm.sh/helm
      name: alpine
      sources:
      - https://github.com/helm/helm
      urls:
      - https://technosophos.github.io/tscharts/alpine-0.2.0.tgz
      version: 0.2.0
    - created: 2016-10-06T16:23:20.499543808-06:00
      description: Deploy a basic Alpine Linux pod
      digest: 515c58e5f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cd78727
      home: https://helm.sh/helm
      name: alpine
      sources:
      - https://github.com/helm/helm
      urls:
      - https://technosophos.github.io/tscharts/alpine-0.1.0.tgz
      version: 0.1.0
  nginx:
    - created: 2016-10-06T16:23:20.499543808-06:00
      description: Create a basic nginx HTTP server
      digest: aaff4545f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cdffffff
      home: https://helm.sh/helm
      name: nginx
      sources:
      - https://github.com/helm/charts
      urls:
      - https://technosophos.github.io/tscharts/nginx-1.1.0.tgz
      version: 1.1.0
generated: 2016-10-06T16:23:20.499029981-06:00`

type Entry struct {
	Created     string `yaml:"created"`
	Description string `yaml:"description"`

	Home string `yaml:"home"`
}
type Entries map[string][]Entry

type Index struct {
	ApiVersion string  `yaml:"apiVersion"`
	Entry      Entries `yaml:"entries"`
	Generated  string  `yaml:"generated"`
}

func main() {

	var index Index
	err := yaml.Unmarshal([]byte(index_yaml), &index)
	if err != nil {
		log.Fatal("File reading error", err)
		return
	}

	fmt.Printf("Index: %+v", index)

}

输出:

Index: {ApiVersion:v1 Entry:map[alpine:[{Created:2016-10-06T16:23:20.499814565-06:00 Description:Deploy a basic Alpine Linux pod Home:https://helm.sh/helm} {Created:2016-10-06T16:23:20.499543808-06:00 Description:Deploy a basic Alpine Linux pod Home:https://helm.sh/helm}] nginx:[{Created:2016-10-06T16:23:20.499543808-06:00 Description:Create a basic nginx HTTP server Home:https://helm.sh/helm}]] Generated:2016-10-06T16:23:20.499029981-06:00}
英文:

Firstly you have to modify the indentation of your yaml input,then modify the Entry Entries from yaml:"entry" to yaml:"entries" as per suggestion:

package main
import (
"fmt"
"log"
"gopkg.in/yaml.v2"
)
const index_yaml = `apiVersion: v1
entries:
alpine:
- created: 2016-10-06T16:23:20.499814565-06:00
description: Deploy a basic Alpine Linux pod
digest: 99c76e403d752c84ead610644d4b1c2f2b453a74b921f422b9dcb8a7c8b559cd
home: https://helm.sh/helm
name: alpine
sources:
- https://github.com/helm/helm
urls:
- https://technosophos.github.io/tscharts/alpine-0.2.0.tgz
version: 0.2.0
- created: 2016-10-06T16:23:20.499543808-06:00
description: Deploy a basic Alpine Linux pod
digest: 515c58e5f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cd78727
home: https://helm.sh/helm
name: alpine
sources:
- https://github.com/helm/helm
urls:
- https://technosophos.github.io/tscharts/alpine-0.1.0.tgz
version: 0.1.0
nginx:
- created: 2016-10-06T16:23:20.499543808-06:00
description: Create a basic nginx HTTP server
digest: aaff4545f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cdffffff
home: https://helm.sh/helm
name: nginx
sources:
- https://github.com/helm/charts
urls:
- https://technosophos.github.io/tscharts/nginx-1.1.0.tgz
version: 1.1.0
generated: 2016-10-06T16:23:20.499029981-06:00`
type Entry struct {
Created     string `yaml:"created"`
Description string `yaml:"description"`
Home string `yaml:"home"`
}
type Entries map[string][]Entry
type Index struct {
ApiVersion string  `yaml:"apiVersion"`
Entry      Entries `yaml:"entries"`
Generated  string  `yaml:"generated"`
}
func main() {
var index Index
err := yaml.Unmarshal([]byte(index_yaml), &index)
if err != nil {
log.Fatal("File reading error", err)
return
}
fmt.Printf("Index: %+v", index)
}

Output:

Index: {ApiVersion:v1 Entry:map[alpine:[{Created:2016-10-06T16:23:20.499814565-06:00 Description:Deploy a basic Alpine Linux pod Home:https://helm.sh/helm} {Created:2016-10-06T16:23:20.499543808-06:00 Description:Deploy a basic Alpine Linux pod Home:https://helm.sh/helm}] nginx:[{Created:2016-10-06T16:23:20.499543808-06:00 Description:Create a basic nginx HTTP server Home:https://helm.sh/helm}]] Generated:2016-10-06T16:23:20.499029981-06:00}

huangapple
  • 本文由 发表于 2021年8月12日 17:49:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/68755123.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定