Created
April 24, 2016 03:04
-
-
Save ivankravchenko/036f68e671e33179b636bd58f6ebc9d0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/pkg/encoding/xml/read.go b/src/pkg/encoding/xml/read.go | |
index c216824..09f0d85 100644 | |
--- a/src/pkg/encoding/xml/read.go | |
+++ b/src/pkg/encoding/xml/read.go | |
@@ -451,6 +451,51 @@ func (p *Decoder) unmarshalPath(tinfo *typeInfo, sv reflect.Value, parents []str | |
Loop: | |
for i := range tinfo.fields { | |
finfo := &tinfo.fields[i] | |
+ if finfo.flags&fAttr != 0 { | |
+ if len(finfo.parents) > len(parents) + 1 { | |
+ recurse = true | |
+ parents = finfo.parents[:len(parents)+1] | |
+ } else if len(finfo.parents) == len(parents) + 1 { | |
+ for _, a := range start.Attr { | |
+ if a.Name.Local == finfo.name { | |
+ v := sv.FieldByIndex(finfo.idx) | |
+ switch v.Kind() { | |
+ case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.String: | |
+ copyValue(v, []byte(a.Value)) | |
+ continue Loop | |
+ case reflect.Slice: | |
+ typ := v.Type() | |
+ if typ.Elem().Kind() == reflect.Uint8 { | |
+ // []byte | |
+ copyValue(v, []byte(a.Value)) | |
+ continue Loop | |
+ } | |
+ | |
+ // Slice of element values. | |
+ // Grow slice. | |
+ n := v.Len() | |
+ if n >= v.Cap() { | |
+ ncap := 2 * n | |
+ if ncap < 4 { | |
+ ncap = 4 | |
+ } | |
+ new := reflect.MakeSlice(typ, n, ncap) | |
+ reflect.Copy(new, v) | |
+ v.Set(new) | |
+ } | |
+ v.SetLen(n + 1) | |
+ | |
+ // Recur to read element into slice. | |
+ copyValue(v.Index(n), []byte(a.Value)) | |
+ continue Loop | |
+ | |
+ default: | |
+ return false, errors.New("unknown type " + v.Type().String()) | |
+ } | |
+ } | |
+ } | |
+ } | |
+ } | |
if finfo.flags&fElement == 0 || len(finfo.parents) < len(parents) { | |
continue | |
} | |
diff --git a/src/pkg/encoding/xml/xml_test.go b/src/pkg/encoding/xml/xml_test.go | |
index 1d0696c..f016507 100644 | |
--- a/src/pkg/encoding/xml/xml_test.go | |
+++ b/src/pkg/encoding/xml/xml_test.go | |
@@ -576,3 +576,92 @@ func TestProcInstEncoding(t *testing.T) { | |
} | |
} | |
} | |
+ | |
+func TestNestedAttr(t *testing.T) { | |
+ type NestedAttr struct { | |
+ Version string `xml:"version,attr"` | |
+ AbName string `xml:"configuration>ab>name,attr"` | |
+ AbVariations int `xml:"configuration>ab>variations,attr"` | |
+ Example string `xml:"configuration>example"` | |
+ } | |
+ var a NestedAttr | |
+ err := Unmarshal([]byte(` | |
+ <rules version="1.0.1"> | |
+ <configuration> | |
+ <ab name="ab test name" variations="5"/> | |
+ <example>example content</example> | |
+ </configuration> | |
+ </rules> | |
+ `), &a) | |
+ expectedNestedAttr := NestedAttr{ | |
+ Version: "1.0.1", | |
+ AbName: "ab test name", | |
+ AbVariations: 5, | |
+ Example: "example content", | |
+ } | |
+ | |
+ if err != nil { | |
+ t.Fatal(err) | |
+ } | |
+ if !reflect.DeepEqual(a, expectedNestedAttr) { | |
+ t.Errorf("have %+v want %+v", a, expectedNestedAttr) | |
+ } | |
+} | |
+ | |
+func TestNestedList(t *testing.T) { | |
+ type NestedList struct { | |
+ Example string `xml:"example"` | |
+ Members []int `xml:"members>member"` | |
+ } | |
+ var a NestedList | |
+ err := Unmarshal([]byte(` | |
+ <output> | |
+ <example>example content</example> | |
+ <members> | |
+ <member>1</member> | |
+ <member>13</member> | |
+ <member>5</member> | |
+ </members> | |
+ </output> | |
+ `), &a) | |
+ expectedNestedList := NestedList{ | |
+ Example: "example content", | |
+ Members: []int{1, 13, 5}, | |
+ } | |
+ | |
+ if err != nil { | |
+ t.Fatal(err) | |
+ } | |
+ if !reflect.DeepEqual(a, expectedNestedList) { | |
+ t.Errorf("have %+v want %+v", a, expectedNestedList) | |
+ } | |
+} | |
+ | |
+func TestNestedAttrList(t *testing.T) { | |
+ type NestedAttrList struct { | |
+ Example string `xml:"example"` | |
+ Members []int `xml:"members>member>id,attr"` | |
+ } | |
+ var a NestedAttrList | |
+ err := Unmarshal([]byte(` | |
+ <output> | |
+ <example>example content</example> | |
+ <members> | |
+ <member id="1"/> | |
+ <member id="13"/> | |
+ <member id="5"/> | |
+ </members> | |
+ </output> | |
+ `), &a) | |
+ expectedNestedAttrList := NestedAttrList{ | |
+ Example: "example content", | |
+ Members: []int{1, 13, 5}, | |
+ } | |
+ | |
+ if err != nil { | |
+ t.Fatal(err) | |
+ } | |
+ if !reflect.DeepEqual(a, expectedNestedAttrList) { | |
+ t.Errorf("have %+v want %+v", a, expectedNestedAttrList) | |
+ } | |
+} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
They should have added your pull request into the core. As I see, they didn't review it yet.