Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Golang: json.Unmarshal is not returning data correctly

Tags:

json

go

I have a json file (themes/snow/theme.json)

{
    Name:'snow',
    Bgimage:'background.jpg',
    Width:600,
    Height:400,
    Itemrotation:'20,40',
    Text:{
        Fontsize:12,
        Color:'#ff00ff',
        Fontfamily:'verdana',
        Bottommargin:20
    },
    Decoration:[
        {
            Path:'abc.jpg',
            X:2,
            Y:4,
            Rotation:0
        },
        {
            Path:'def.png',
            X:4,
            Y:22,
            Rotation:10
        }
    ]
}

And I have a file that parse the json data

package main

import (
    "fmt"
    "os"
    "encoding/json"
    "io/ioutil"
    "log"
)

const themeDirectory    = "themes"
const themeJsonFile     = "theme.json"

type TextInfo struct {
    Fontsize        int
    Color           string
    Fontfamily      string
    Bottommargin    int
}

type DecoInfo struct {
    Path            string
    X               int
    Y               int
    Rotation        int
}

type ThemeInfo struct {
    Name            string
    Bgimage         string
    Width           int
    Height          int
    Itemrotation    string
    Text            textInfo
    Decoration      []decoInfo
}

func main() {
    var tinfo = parseTheme("snow")
        //use tinfo to build graphics
}

func parseTheme(themename string) themeInfo {
    abspath, _ := os.Getwd()
    filename :=  abspath + "/" + themeDirectory + "/" + themename + "/" + themeJsonFile

    //Check this file exists
    if _, error := os.Stat(filename); error != nil {
        if os.IsNotExist(error) {
            log.Fatal(filename + " does not exist")
            os.Exit(1)
        }
    } 

    filebyte, error := ioutil.ReadFile(filename) 
    if error != nil { 
        log.Fatal("Could not read file " + filename + " to parse")
        os.Exit(1) 
    } 

    var t themeInfo
    json.Unmarshal(filebyte, &t) 
    fmt.Println(t)
    return t
}

You can see I have 2 lines before the end

 fmt.Println(t)

I am not sure why does it print

{  0 0  {0   0} []}

I expect it should return me themeInfo in a usable way, so that I can use it for further processing.What am I doing wrong here?

like image 436
JVK Avatar asked Nov 29 '22 02:11

JVK


2 Answers

As the json package uses reflection to dissect your structs, it can only see fields that are exported. All of your field names begin with lower case letters, therefore they are not exported. Change the names to start with upper case letters and I suspect it will start working for you.

like image 157
Matt Avatar answered Dec 23 '22 22:12

Matt


Your JSON is not valid. JavaScript allows single quotes; JSON does not. Further, the object keys must be double quoted:

Valid:

{ "name": "Simon" }

Invalid:

{ name: "Simon" }
{ 'name': "Simon" }
{ "name": 'Simon' }

If you wrap your JSON keys and values with double quotes, you'll see the expected output:

{snow background.jpg 600 400 20,40 {12 #ff00ff verdana 20} [{abc.jpg 2 4 0} {def.png 4 22 10}]}

For exmaple,

const sampleTheme       = `{
    "Name":"snow",
    "Bgimage":"background.jpg",
    "Width":600,
    "Height":400,
    "Itemrotation":"20,40",
    "Text":{
        "Fontsize":12,
        "Color":"#ff00ff",
        "Fontfamily":"verdana",
        "Bottommargin":20
    },
    "Decoration":[
        {
            "Path":"abc.jpg",
            "X":2,
            "Y":4,
            "Rotation":0
        },
        {
            "Path":"def.png",
            "X":4,
            "Y":22,
            "Rotation":10
        }
    ]
}`

For the full program, see: http://play.golang.org/p/SLhaLbJcla

like image 25
Sridhar Ratnakumar Avatar answered Dec 23 '22 21:12

Sridhar Ratnakumar