mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
xml: handle tag paths through the same element
With the current implementation, xml unmarshalling
will silently fail to unmarshal any paths passing
through the same element, such as:
type T struct {
A string "dummy>a"
B string "dummy>b"
}
This change tweaks the algorithm so that this works
correctly.
Also, using paths that would cause the same element to
unmarshal twice will error out ahead of time explaining
the problem, rather than silently misbehaving.
R=rsc
CC=golang-dev
https://golang.org/cl/4082041
This commit is contained in:
parent
b99a6d465a
commit
c52ad23461
2 changed files with 111 additions and 35 deletions
|
|
@ -235,16 +235,16 @@ const pathTestString = `
|
|||
<result>
|
||||
<before>1</before>
|
||||
<items>
|
||||
<item>
|
||||
<item1>
|
||||
<value>A</value>
|
||||
</item>
|
||||
<skip>
|
||||
</item1>
|
||||
<item2>
|
||||
<value>B</value>
|
||||
</skip>
|
||||
<Item>
|
||||
</item2>
|
||||
<Item1>
|
||||
<Value>C</Value>
|
||||
<Value>D</Value>
|
||||
</Item>
|
||||
</Item1>
|
||||
</items>
|
||||
<after>2</after>
|
||||
</result>
|
||||
|
|
@ -255,22 +255,23 @@ type PathTestItem struct {
|
|||
}
|
||||
|
||||
type PathTestA struct {
|
||||
Items []PathTestItem ">item"
|
||||
Items []PathTestItem ">item1"
|
||||
Before, After string
|
||||
}
|
||||
|
||||
type PathTestB struct {
|
||||
Other []PathTestItem "items>Item"
|
||||
Other []PathTestItem "items>Item1"
|
||||
Before, After string
|
||||
}
|
||||
|
||||
type PathTestC struct {
|
||||
Values []string "items>item>value"
|
||||
Values1 []string "items>item1>value"
|
||||
Values2 []string "items>item2>value"
|
||||
Before, After string
|
||||
}
|
||||
|
||||
type PathTestSet struct {
|
||||
Item []PathTestItem
|
||||
Item1 []PathTestItem
|
||||
}
|
||||
|
||||
type PathTestD struct {
|
||||
|
|
@ -281,8 +282,8 @@ type PathTestD struct {
|
|||
var pathTests = []interface{}{
|
||||
&PathTestA{Items: []PathTestItem{{"A"}, {"D"}}, Before: "1", After: "2"},
|
||||
&PathTestB{Other: []PathTestItem{{"A"}, {"D"}}, Before: "1", After: "2"},
|
||||
&PathTestC{Values: []string{"A", "C", "D"}, Before: "1", After: "2"},
|
||||
&PathTestD{Other: PathTestSet{Item: []PathTestItem{{"A"}, {"D"}}}, Before: "1", After: "2"},
|
||||
&PathTestC{Values1: []string{"A", "C", "D"}, Values2: []string{"B"}, Before: "1", After: "2"},
|
||||
&PathTestD{Other: PathTestSet{Item1: []PathTestItem{{"A"}, {"D"}}}, Before: "1", After: "2"},
|
||||
}
|
||||
|
||||
func TestUnmarshalPaths(t *testing.T) {
|
||||
|
|
@ -298,3 +299,31 @@ func TestUnmarshalPaths(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
type BadPathTestA struct {
|
||||
First string "items>item1"
|
||||
Other string "items>item2"
|
||||
Second string "items>"
|
||||
}
|
||||
|
||||
type BadPathTestB struct {
|
||||
Other string "items>item2>value"
|
||||
First string "items>item1"
|
||||
Second string "items>item1>value"
|
||||
}
|
||||
|
||||
var badPathTests = []struct {
|
||||
v, e interface{}
|
||||
}{
|
||||
{&BadPathTestA{}, &TagPathError{reflect.Typeof(BadPathTestA{}), "First", "items>item1", "Second", "items>"}},
|
||||
{&BadPathTestB{}, &TagPathError{reflect.Typeof(BadPathTestB{}), "First", "items>item1", "Second", "items>item1>value"}},
|
||||
}
|
||||
|
||||
func TestUnmarshalBadPaths(t *testing.T) {
|
||||
for _, tt := range badPathTests {
|
||||
err := Unmarshal(StringReader(pathTestString), tt.v)
|
||||
if !reflect.DeepEqual(err, tt.e) {
|
||||
t.Fatalf("Unmarshal with %#v didn't fail properly: %#v", tt.v, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue