Skip to content

Commit

Permalink
Add/refactor wrapper functions
Browse files Browse the repository at this point in the history
  • Loading branch information
clbanning committed Sep 14, 2018
1 parent abc2aec commit be7b154
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 2 deletions.
61 changes: 61 additions & 0 deletions examples/reddit02.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// https://www.reddit.com/r/golang/comments/9eclgy/xml_unmarshaling_internal_references/

package main

import (
"fmt"

"github.com/clbanning/mxj"
)

var data = []byte(`<app>
<users>
<user id="1" name="Jeff" />
<user id="2" name="Sally" />
</users>
<messages>
<message id="1" from_user="1" to_user="2">Hello!!</message>
</messages>
</app>`)

func main() {
m, err := mxj.NewMapXml(data)
if err != nil {
fmt.Println("err:", err)
return
}
fmt.Printf("%v\n", m)

type mystruct struct {
FromUser string
ToUser string
Message string
}
myStruct := mystruct{}
val, err := m.ValueForKey("user", "-id:1")
if val != nil {
myStruct.FromUser = val.(map[string]interface{})["-name"].(string)
} else {
// if there no val, then err is at least KeyNotExistError
fmt.Println("err:", err)
return
}
val, err = m.ValueForKey("user", "-id:2")
if val != nil {
myStruct.ToUser = val.(map[string]interface{})["-name"].(string)
} else {
// if there no val, then err is at least KeyNotExistError
fmt.Println("err:", err)
return
}
val, err = m.ValueForKey("#text")
if val != nil {
myStruct.Message = val.(string)
} else {
// if there no val, then err is at least KeyNotExistError
fmt.Println("err:", err)
return
}

fmt.Printf("%#v\n", myStruct)
}
22 changes: 20 additions & 2 deletions keyvalues.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,21 @@ func (mv Map) ValuesForKey(key string, subkeys ...string) ([]interface{}, error)
return ret[:cnt], nil
}

var KeyNotExistError = errors.New("Key does not exist")

// ValueForKey is a wrapper on ValuesForKey. It returns the first member of []interface{}, if any.
// If there is no value, "nil, nil" is returned.
func (mv Map) ValueForKey(key string, subkeys ...string) (interface{}, error) {
vals, err := mv.ValuesForKey(key, subkeys...)
if err != nil {
return nil, err
}
if len(vals) == 0 {
return nil, KeyNotExistError
}
return vals[0], nil
}

// hasKey - if the map 'key' exists append it to array
// if it doesn't do nothing except scan array and map values
func hasKey(iv interface{}, key string, ret *[]interface{}, cnt *int, subkeys map[string]interface{}) {
Expand Down Expand Up @@ -615,14 +630,17 @@ func hasKeyPath(crumbs string, iv interface{}, key string, basket map[string]boo
}
}

// Returns the first found value for the path.
var PathNotExistError = errors.New("Path does not exist")

// ValueForPath wrap ValuesFor Path and returns the first value returned.
// If no value is found it returns 'nil' and PathNotExistError.
func (mv Map) ValueForPath(path string) (interface{}, error) {
vals, err := mv.ValuesForPath(path)
if err != nil {
return nil, err
}
if len(vals) == 0 {
return nil, errors.New("ValueForPath: path not found")
return nil, PathNotExistError
}
return vals[0], nil
}
Expand Down
46 changes: 46 additions & 0 deletions keyvalues_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -444,3 +444,49 @@ func TestValueForPathString(t *testing.T) {
t.Fatal("wrong value")
}
}

func TestValueForPathError(t *testing.T) {
m := map[string]interface{}{
"Div": map[string]interface{}{
"Colour": "blue",
},
}
mv := Map(m)

_, err := mv.ValueForPath("Color")
if err != PathNotExistError {
t.Fatal("no PathNotExistError returned")
}
}

func TestValueForKey(t *testing.T) {
m := map[string]interface{}{
"Div": map[string]interface{}{
"Colour": "blue",
},
}
mv := Map(m)

v, err := mv.ValueForKey("Colour")
if err != nil {
t.Fatal(err)
}
if str, ok := v.(string); !ok || str != "blue" {
t.Fatal("wrong value")
}
}

func TestValueForKeyError(t *testing.T) {
m := map[string]interface{}{
"Div": map[string]interface{}{
"Colour": "blue",
},
}
mv := Map(m)

_, err := mv.ValueForKey("Color")
if err != KeyNotExistError {
t.Fatal("no KeyNotExistError returned")
}
}

0 comments on commit be7b154

Please sign in to comment.