Gerrit Bot has uploaded this change for review.
encoding/xml: allow mismatched `XMLName` / field metadata tag names
Currently, if you have nested structs, where the inner struct’s
XMLName doesn’t match the outer struct’s field name metadata, such as:
type InnerStruct struct {
XMLName Name `xml:"innerStruct"`
Name string `xml:"name"`
}
type Outer struct {
XMLName Name `xml:"outer"`
Inner *InnerStruct `xml:"inner"`
}
Then decoding XML produces an error:
xml: name "inner" in tag of xml.Outer.Inner conflicts with name "innerStruct" in *xml.InnerStruct.XMLName
This causes issues when interacting with SOAP web services, whose
WSDLs are expressed with XSD. XSD allows defining reusable types;
each of those types has a unique name. That name MAY be the name of
the tag containing the struct’s data, but isn’t ALWAYS. An
xsd:element may specify a different tag name to contain an XSD type’s
values. An illustration of a real-world case where this happens is
hooklift/gowsdl#219.
This PR uses the big hammer of removing the tests and errors which
cause the issue. I’m reasonably certain that the structFieldInfo()
changes are fine, but I feel less good about Decoder.unmarshal().
Ideally, that code would look at the field metadata of the containing
struct, then the XMLName of the destination struct. I’m not familiar
with this code, but it looks like the parent element isn’t accessible
at the time when this check would need to happen, so I opted to remove
it instead.
fixes hooklift/gowsdl#219
Change-Id: I94714926f9aa0ab3588b4de25a35a33a1baf2e39
GitHub-Last-Rev: 22d97c4f9443c0d7fa49273452588aa3aeed738c
GitHub-Pull-Request: golang/go#48450
---
M src/encoding/xml/typeinfo.go
M src/encoding/xml/read.go
M src/encoding/xml/marshal_test.go
3 files changed, 78 insertions(+), 14 deletions(-)
diff --git a/src/encoding/xml/marshal_test.go b/src/encoding/xml/marshal_test.go
index d2e5137..c54db08 100644
--- a/src/encoding/xml/marshal_test.go
+++ b/src/encoding/xml/marshal_test.go
@@ -2490,3 +2490,34 @@
t.Errorf("error %q does not contain %q", err, want)
}
}
+
+func TestMismatchedTagNames(t *testing.T) {
+ type InnerStruct struct {
+ XMLName Name `xml:"innerStruct"`
+ Name string `xml:"name"`
+ }
+
+ type Outer struct {
+ XMLName Name `xml:"outer"`
+ Inner *InnerStruct `xml:"inner"`
+ }
+
+ dec := NewDecoder(strings.NewReader(`<?xml version="1.0"?>
+<outer>
+ <inner>
+ <name>foo</name>
+ </inner>
+</outer>"`))
+
+ holder := &Outer{}
+ if err := dec.Decode(holder); err != nil {
+ t.Errorf("Unexpected error: %q", err)
+ }
+ if holder == nil {
+ t.Error("Holder should be non-nil")
+ } else if holder.Inner == nil {
+ t.Error("Inner should be non-nil")
+ } else if holder.Inner.Name != "foo" {
+ t.Errorf("Expected name to be %q, but was %q", "foo", holder.Inner.Name)
+ }
+}
diff --git a/src/encoding/xml/read.go b/src/encoding/xml/read.go
index ef5df3f..20172b8 100644
--- a/src/encoding/xml/read.go
+++ b/src/encoding/xml/read.go
@@ -423,9 +423,6 @@
// Validate and assign element name.
if tinfo.xmlname != nil {
finfo := tinfo.xmlname
- if finfo.name != "" && finfo.name != start.Name.Local {
- return UnmarshalError("expected element type <" + finfo.name + "> but have <" + start.Name.Local + ">")
- }
if finfo.xmlns != "" && finfo.xmlns != start.Name.Space {
e := "expected element <" + finfo.name + "> in name space " + finfo.xmlns + " but have "
if start.Name.Space == "" {
diff --git a/src/encoding/xml/typeinfo.go b/src/encoding/xml/typeinfo.go
index 162724e..0053947 100644
--- a/src/encoding/xml/typeinfo.go
+++ b/src/encoding/xml/typeinfo.go
@@ -211,17 +211,6 @@
finfo.parents = parents[:len(parents)-1]
}
- // If the field type has an XMLName field, the names must match
- // so that the behavior of both marshaling and unmarshaling
- // is straightforward and unambiguous.
- if finfo.flags&fElement != 0 {
- ftyp := f.Type
- xmlname := lookupXMLName(ftyp)
- if xmlname != nil && xmlname.name != finfo.name {
- return nil, fmt.Errorf("xml: name %q in tag of %s.%s conflicts with name %q in %s.XMLName",
- finfo.name, typ, f.Name, xmlname.name, ftyp)
- }
- }
return finfo, nil
}
To view, visit change 353394. To unsubscribe, or for help writing mail filters, visit settings.
Gopher Robot abandoned this change.
To view, visit change 353394. To unsubscribe, or for help writing mail filters, visit settings.