...
1 package mxj
2
3
4
5
6 import (
7 "strconv"
8 "strings"
9 )
10
11 const (
12 NoAttributes = true
13 )
14
15
16
17
18
19 type LeafNode struct {
20 Path string
21 Value interface{}
22 }
23
24
25
26
27
28
29
30
31
32
33
34 func (mv Map) LeafNodes(no_attr ...bool) []LeafNode {
35 var a bool
36 if len(no_attr) == 1 {
37 a = no_attr[0]
38 }
39
40 l := make([]LeafNode, 0)
41 getLeafNodes("", "", map[string]interface{}(mv), &l, a)
42 return l
43 }
44
45 func getLeafNodes(path, node string, mv interface{}, l *[]LeafNode, noattr bool) {
46
47 if !noattr || node != textK {
48 if path != "" && node[:1] != "[" {
49 path += "."
50 }
51 path += node
52 }
53 switch mv.(type) {
54 case map[string]interface{}:
55 for k, v := range mv.(map[string]interface{}) {
56
57 if noattr && len(attrPrefix) > 0 && strings.Index(k, attrPrefix) == 0 {
58 continue
59 }
60 getLeafNodes(path, k, v, l, noattr)
61 }
62 case []interface{}:
63 for i, v := range mv.([]interface{}) {
64 if useDotNotation {
65 getLeafNodes(path, strconv.Itoa(i), v, l, noattr)
66 } else {
67 getLeafNodes(path, "["+strconv.Itoa(i)+"]", v, l, noattr)
68 }
69 }
70 default:
71
72 n := LeafNode{path, mv}
73 *l = append(*l, n)
74 }
75 }
76
77
78 func (mv Map) LeafPaths(no_attr ...bool) []string {
79 ln := mv.LeafNodes()
80 ss := make([]string, len(ln))
81 for i := 0; i < len(ln); i++ {
82 ss[i] = ln[i].Path
83 }
84 return ss
85 }
86
87
88 func (mv Map) LeafValues(no_attr ...bool) []interface{} {
89 ln := mv.LeafNodes()
90 vv := make([]interface{}, len(ln))
91 for i := 0; i < len(ln); i++ {
92 vv[i] = ln[i].Value
93 }
94 return vv
95 }
96
97
98
99
100 var useDotNotation bool
101
102
103
104
105
106 func LeafUseDotNotation(b ...bool) {
107 if len(b) == 0 {
108 useDotNotation = !useDotNotation
109 return
110 }
111 useDotNotation = b[0]
112 }
113
View as plain text