dongxun3777 2018-12-24 16:12
浏览 289
已采纳

为TOML文件和golang解析表中的键值对

I have the following structure for a TOML file:

[database]
host = "localhost"
port = 8086
https = true
username = "root"
password = "root"
db = "test"

[cloud]
deviceType = "2be386e9bbae"
deviceId = "119a705fa3b1"
password = "test"
token = "dqpx5vNLLTR34"
endpoint = "mqtts://mqtt1.endpoint.com"

[gps]
#measurement = "gps"
  [gps.msgpack]
  topic = "/evt/gps/msgpack"

  [gps.json]
  topic = "/evt/gps/json"

[imu]
#measurement = "imu"
  [imu.1]
    tag = "NODE1"
    topic = "/evt/imu1/msgpack"
  [imu.2]
    tag = "NODE2"
    topic = "/evt/imu2/msgpack"

I want to set measurement key in gps table and imutable only once and not redundantly within msgpack and json and for 1 and 2

With the commented out keys The following code works

Code

package main

import (
  "fmt"
  "github.com/BurntSushi/toml"
)

type imu struct {
  Topic string
  Measurement string
  Tag string
}

type gps struct {
  // Measurement string
  Measurement string
  ETopic string `toml:"topic"`
}

type database struct {
  Host  string
  Port  int
  Https bool
  Username  string
  Password  string
  Dbname  string
}

type cloud struct {
  Devicetype  string
  DeviceId  string
  Password  string
  Token   string
  Endpoint  string
}

type tomlConfig struct {
  DB database `toml:"database"`
  Cloud cloud `toml:"cloud"`
  Gps map[string]gps `toml:"gps"`
  Imu map[string]imu  `toml:"imu"`
}


func main()  {

  var config tomlConfig

  if _, err := toml.DecodeFile("cloud.toml", &config); err != nil {
    fmt.Println(err)
    return
  }
  // fmt.Printf("%#v
", config)
  for sensorName, sensor := range config.Imu {
    fmt.Printf("Topic: %s %s %s %s
", sensorName, sensor.Topic, sensor.Tag, sensor.Measurement)
  }

  for types, gps := range config.Gps {
    fmt.Printf("%s
", types)
    fmt.Printf("%s
", gps.ETopic)
  }
}

However on uncommenting out the key value pair I get the following:

 toml: type mismatch for main.gps: expected table but found string

(It should still be a valid TOML, as I translated it to JSON and checked the structure)

I understand that I have not mentioned within the struct that I need to add a string for it. However I am getting confused as to how the struct should now look like.

  • 写回答

1条回答 默认 最新

  • duanliusong6395 2018-12-25 11:19
    关注

    You say:

    I want to set measurement key in gps table and imutable only once and not redundantly within msgpack and json and for 1 and 2

    You don't make this because creator of TOML format said:

    Because we need a decent human-readable format that unambiguously maps to a hash table and the YAML spec is like 80 pages long and gives me rage. No, JSON doesn't count. You know why.

    If you need to have the same value to one key, for you example, measurement, you must specify it in every subtable what you want

    Your correct TOML file:

    [database]
    host = "localhost"
    port = 8086
    https = true
    username = "root"
    password = "root"
    db = "test"
    
    [cloud]
    deviceType = "2be386e9bbae"
    deviceId = "119a705fa3b1"
    password = "test"
    token = "dqpx5vNLLTR34"
    endpoint = "mqtts://mqtt1.endpoint.com"
    
    [gps]
    [gps.msgpack]
    topic = "/evt/gps/msgpack"
    measurement = "gps"
    
    [gps.json]
    topic = "/evt/gps/json"
    measurement = "gps"
    
    [imu]
    [imu.1]
    measurement = "imu"
    tag = "NODE1"
    topic = "/evt/imu1/msgpack"
    [imu.2]
    measurement = "imu"
    tag = "NODE2"
    topic = "/evt/imu2/msgpack"
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?