-
Notifications
You must be signed in to change notification settings - Fork 1
/
flatjson.go
89 lines (71 loc) · 1.94 KB
/
flatjson.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package main
import (
"encoding/json"
flag "github.com/spf13/pflag"
"io/ioutil"
"os"
)
func check(e error) {
if e != nil {
panic(e)
}
}
func flatten(acc []map[string]interface{}, curr interface{}, key string, id, parentid int, idname, parentidname, parentrefname string) ([]map[string]interface{}, int) {
var cid int
switch t := curr.(type) {
case map[string]interface{}:
id++
t[idname] = id
t[parentidname] = parentid
t[parentrefname] = key
parentid = id
acc = append(acc, t)
for k, v := range t {
if acc, cid = flatten(acc, v, k, id, parentid, idname, parentidname, parentrefname); cid != 0 {
delete(t, k)
id = cid
}
}
return acc, id
case []interface{}:
for _, v := range t {
if acc, cid = flatten(acc, v, key, id, parentid, idname, parentidname, parentrefname); cid != 0 {
id = cid
}
}
return acc, id
default:
return acc, 0
}
}
func main() {
fileIn := flag.StringP("file", "f", "", "input file")
fileOut := flag.StringP("output", "o", "", "output file")
firstId := flag.Int("id", 1, "begin id numbering with")
nameId := flag.String("propid", "_id", "id property name")
nameParentId := flag.String("parentid", "_parentid", "parent id property name")
nameParentRef := flag.String("ref", "_parentref", "parent ref property name")
flag.Parse()
var data []byte
var err error
if *fileIn == "" {
data, err = ioutil.ReadAll(os.Stdin)
check(err)
} else {
data, err = ioutil.ReadFile(*fileIn)
check(err)
}
var dat interface{}
err = json.Unmarshal(data, &dat)
check(err)
flat, _ := flatten(make([]map[string]interface{}, 0), dat, "", *firstId, *firstId, *nameId, *nameParentId, *nameParentRef)
var out []byte
out, err = json.MarshalIndent(flat, "", " ")
check(err)
if *fileOut == "" {
_, err = os.Stdout.Write(out)
} else {
err = ioutil.WriteFile(*fileOut, out, 0644)
}
check(err)
}