...
1
2
3
4
5
6
7 package x2j
8
9 import (
10 "strings"
11
12 "github.com/clbanning/mxj"
13 )
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 func ValuesFromTagPath(doc, path string, getAttrs ...bool) ([]interface{}, error) {
29 var a bool
30 if len(getAttrs) == 1 {
31 a = getAttrs[0]
32 }
33 m, err := mxj.NewMapXml([]byte(doc))
34 if err != nil {
35 return nil, err
36 }
37
38 v := ValuesFromKeyPath(m, path, a)
39 return v, nil
40 }
41
42
43
44
45
46
47
48
49 func ValuesFromKeyPath(m map[string]interface{}, path string, getAttrs ...bool) []interface{} {
50 var a bool
51 if len(getAttrs) == 1 {
52 a = getAttrs[0]
53 }
54 keys := strings.Split(path, ".")
55 ret := make([]interface{}, 0)
56 valuesFromKeyPath(&ret, m, keys, a)
57 if len(ret) == 0 {
58 return nil
59 }
60 return ret
61 }
62
63 func valuesFromKeyPath(ret *[]interface{}, m interface{}, keys []string, getAttrs bool) {
64 lenKeys := len(keys)
65
66
67
68 if lenKeys == 0 {
69 switch m.(type) {
70 case map[string]interface{}:
71 *ret = append(*ret, m)
72 case []interface{}:
73 for _, v := range m.([]interface{}) {
74 *ret = append(*ret, v)
75 }
76 default:
77 *ret = append(*ret, m)
78 }
79 return
80 }
81
82
83 key := keys[0]
84 switch key {
85 case "*":
86 switch m.(type) {
87 case map[string]interface{}:
88 for k, v := range m.(map[string]interface{}) {
89 if string(k[:1]) == "-" && !getAttrs {
90 continue
91 }
92 valuesFromKeyPath(ret, v, keys[1:], getAttrs)
93 }
94 case []interface{}:
95 for _, v := range m.([]interface{}) {
96 switch v.(type) {
97
98 case map[string]interface{}:
99 for kk, vv := range v.(map[string]interface{}) {
100 if string(kk[:1]) == "-" && !getAttrs {
101 continue
102 }
103 valuesFromKeyPath(ret, vv, keys[1:], getAttrs)
104 }
105 default:
106 valuesFromKeyPath(ret, v, keys[1:], getAttrs)
107 }
108 }
109 }
110 default:
111 switch m.(type) {
112 case map[string]interface{}:
113 if v, ok := m.(map[string]interface{})[key]; ok {
114 valuesFromKeyPath(ret, v, keys[1:], getAttrs)
115 }
116 case []interface{}:
117 for _, v := range m.([]interface{}) {
118 switch v.(type) {
119 case map[string]interface{}:
120 if vv, ok := v.(map[string]interface{})[key]; ok {
121 valuesFromKeyPath(ret, vv, keys[1:], getAttrs)
122 }
123 }
124 }
125 }
126 }
127 }
128
View as plain text