2017-12-20 18 views
4

次のコードを使用してyamlを構造体に解析しても問題ありません。 今、あなたは、任意のキーvalのプロパティを取得することができます、我々は変更される可能性があり、追加key val propertiesを持つことができるのは、私はほかにNameGroupしかしのような2つのconstのpropertiesを持っている私が知っているinstallのような構造体を持っていると仮定しましょう(ダイナミック)yamlを解析して動的フィールドを構造化する

この構造体はどのように定義する必要がありますか?アイデアはyamlファイルを読み取ることですいくつかの値を変更してしたがって(正確に同じ構造を変更して)それを書き換えます私はいくつかの動的なフィールドをいくつか見逃したくありません変更する必要がYAMLファイル

import (
    "fmt" 
    "log" 

    "github.com/go-yaml/yaml" 
) 

type File struct { 
    TypeVersion string `yaml:"_type-version"` 
    Dependency []Dependency 
} 

type Dependency struct { 
    Name  string 
    Type  string 
    CWD  string 
    Install []Install 
    Requires []Requires 
} 

type Install struct { 
    Name string 
    Group string 
    //Here any key value can be 
} 

type Requires struct { 
    Name string 
    Type string 
} 

var data = ` 
_type-version: "1.0.0" 
dependency: 
    - name: ui 
    type: runner 
    cwd: /ui 
    install: 
     - name: api 
     group: test 
    requires: 
     - name: db 
     - type: mongo 
     - name: rst 
     - name: test 
     - name: test2 
` 

func main() { 
    f := File{} 

    err := yaml.Unmarshal([]byte(data), &f) 
    if err != nil { 
     log.Fatalf("error: %v", err) 
    } 
    fmt.Printf("--- t:\n%v\n\n", f) 

    d, err := yaml.Marshal(&f) 
    if err != nil { 
     log.Fatalf("error: %v", err) 
    } 
    fmt.Printf("--- t dump:\n%s\n\n", string(d)) 
} 

パッケージ例 Installは、上記と、この

等のようにすることができ name後0

install: 
      - name: api 
      group: test 
      z10:123 
      zzz:111 

そして、より多くのフィールド、代わりにインストールのための構造体のgroup

+0

あなたは[viper](https://github.com/spf13/viper)を見ましたか?構造体にYAMLデータをロードするのではなく、 'viper.Get()'でジェネリックルックアップを作成し、必要なものにリターンをアサートします。 "ダイナミック"アクセスが必要で、すべての可能なキーで構造体を定義したくない場合は、バイパーを使いやすくすることができます。 – rjsberry

+0

マップはおそらく?ちょっと推測します.... – Volker

+0

@Volker - ありがとう、マップには[インタフェース{} {インタフェース} {インタフェース}のオプションがありますが、私のコンテキストでどのように使用するかはわかりません... –

答えて

1

地図は、問題を解決するのに役立ちます。

import (
    "fmt" 
    "log" 

    "github.com/go-yaml/yaml" 
) 

type File struct { 
    TypeVersion string `yaml:"_type-version"` 
    Dependency []Dependency 
} 

type Dependency struct { 
    Name  string 
    Type  string 
    CWD  string 
    Install []Install 
    Requires []Requires 
} 

type Install map[string]string 

func (i Install) name() string { 
    return i["name"] 
} 

func (i Install) group() string { 
    return i["group"] 
} 

type Requires struct { 
    Name string 
    Type string 
} 

var data = ` 
_type-version: "1.0.0" 
dependency: 
    - name: ui 
    type: runner 
    cwd: /ui 
    install: 
     - name: api 
     group: test 
    requires: 
     - name: db 
     - type: mongo 
     - name: rst 
     - name: test 
     - name: test2 
` 

func main() { 
    f := File{} 

    err := yaml.Unmarshal([]byte(data), &f) 
    if err != nil { 
     log.Fatalf("error: %v", err) 
    } 
    fmt.Printf("--- t:\n%v\n\n", f) 

    d, err := yaml.Marshal(&f) 
    if err != nil { 
     log.Fatalf("error: %v", err) 
    } 
    fmt.Printf("--- t dump:\n%s\n\n", string(d)) 
} 
+0

ありがとうございます。 'name'と' group'は何らかのconstであり、 'a1''b1''z10'はdiffキーフィールドで多くのことができるいくつかの動的なフィールドです。あなたはそのようなダイナミックなフィールドをどのように解析するでしょうか? –

+0

インストールは単なる地図です。マップを範囲指定(ループ)するか、マップを検索するためのキーを受け取るget funcを記述することができます。これらの関数を使って動的なフィールドを簡単に取得できます。 – Spartan

関連する問題