Skip to content

Instantly share code, notes, and snippets.

@rambattu
Last active March 23, 2019 17:32
Show Gist options
  • Save rambattu/10a77db7cb94a95c3dd56c9deb57a9f4 to your computer and use it in GitHub Desktop.
Save rambattu/10a77db7cb94a95c3dd56c9deb57a9f4 to your computer and use it in GitHub Desktop.
Go nested JSON parsing
package main
import (
"encoding/json"
"fmt"
"log"
)
type DataMap struct {
Data string `json:"data"`
}
type CONTENTS struct {
Llpi []DataMap `json:"lldp-local-port-id"`
Lrpi []DataMap `json:"lldp-remote-port-id"`
Lrsn []DataMap `json:"lldp-remote-system-name"`
}
type LNI struct {
Contents []CONTENTS `json:"lldp-neighbor-information"`
}
type LNsI struct {
Lni []LNI `json:"lldp-neighbors-information"`
}
func main() {
var data = []byte(`
{
"lldp-neighbors-information" : [
{
"lldp-neighbor-information" : [
{
"lldp-local-port-id" : [
{
"data" : "ge-0/0/1"
}
],
"lldp-local-parent-interface-name" : [
{
"data" : "-"
}
],
"lldp-remote-chassis-id-subtype" : [
{
"data" : "Mac address"
}
],
"lldp-remote-chassis-id" : [
{
"data" : "ac:bc:dc:ef:gh:ij"
}
],
"lldp-remote-port-id-subtype" : [
{
"data" : "Interface name"
}
],
"lldp-remote-port-id" : [
{
"data" : "ge-0/0/1"
}
],
"lldp-remote-system-name" : [
{
"data" : "testmachine.localnet.com"
}
]
}
]
}
]
}`)
var lnsi LNsI
if err := json.Unmarshal(data, &lnsi); err != nil {
log.Fatal(err)
}
fmt.Printf("%+v\n", lnsi)
fmt.Println("Local LLDP port:", lnsi.Lni[0].Contents[0].Llpi[0].Data)
fmt.Println("Remote LLDP port:", lnsi.Lni[0].Contents[0].Lrpi[0].Data)
fmt.Println("Remote System Name:", lnsi.Lni[0].Contents[0].Lrsn[0].Data)
}

In Go, to parse arbitrary nested structures one might have to build the struct constructs to map the content into Go variables.

This blog post had good info on creating the struct mapping for parsing JSON data https://blog.serverbooter.com/post/parsing-nested-json-in-go/

Modified the code snippet a little bit to see how to parse multiple nested structs https://play.golang.org/p/gchJXpIGKCU

In this particular snippet, I am trying to get the values for fields lldp-local-port-id, lldp-remote-port-id, lldp-remote-system-name from the JSON output of cli command "show lldp neighbors"

JSON string output for "show lldp neighbors"

{
    "lldp-neighbors-information" : [
    {
        "lldp-neighbor-information" : [
        {
            "lldp-local-port-id" : [
            {
                "data" : "ge-0/0/1"
            }
            ],
            "lldp-local-parent-interface-name" : [
            {
                "data" : "-"
            }
            ],
            "lldp-remote-chassis-id-subtype" : [
            {
                "data" : "Mac address"
            }
            ],
            "lldp-remote-chassis-id" : [
            {
                "data" : "ac:bc:dc:ef:gh:ij"
            }
            ],
            "lldp-remote-port-id-subtype" : [
            {
                "data" : "Interface name"
            }
            ],
            "lldp-remote-port-id" : [
            {
                "data" : "ge-0/0/1"
            }
            ],
            "lldp-remote-system-name" : [
            {
                "data" : "testmachine.localnet.com"
            }
            ]
        }
        ]
    }
    ]
}

This is the type that gets returned for this particular JSON.

    // map[lldp-neighbors-information:
    //	[map[lldp-neighbor-information:
    //		[map[lldp-remote-chassis-id-subtype: [map[data:Mac address]]
    //			lldp-remote-chassis-id:[map[data:2c:6b:f5:d8:4a:c0]]
    //			lldp-remote-port-id-subtype:[map[data:Interface name]]
    //			lldp-remote-port-id:[map[data:ge-0/0/1]]
    //			lldp-remote-system-name:[map[data:riad001-x.englab.juniper.net]]
    //			lldp-local-port-id:[map[data:ge-0/0/1]]
    //			lldp-local-parent-interface-name:[map[data:-]]]]]]]

Snippet can be tried in the Go playground here: https://play.golang.org/p/mu3nZUl_rJ9

Output from the program

Output
{Lni:[{Contents:[{Llpi:[{Data:ge-0/0/1}] Lrpi:[{Data:ge-0/0/1}] Lrsn:[{Data:testmachine.localnet.com}]}]}]}
Local LLDP port: ge-0/0/1
Remote LLDP port: ge-0/0/1
Remote System Name: testmachine.localnet.com
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment