Skip to content

encoding/xml: embedded interface doesn't get marshaled correctly #69941

Closed
@otaxhu

Description

@otaxhu

Go version

go version go1.22.4 linux/amd64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/albian/.cache/go-build'
GOENV='/home/albian/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/albian/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/albian/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/opt/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/opt/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.22.4'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/home/albian/dev/problem/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2437414976=/tmp/go-build -gno-record-gcc-switches'

What did you do?

Embedding interface type in a struct, pass struct that implements that interface, then marshal it:
https://go.dev/play/p/SBfpU8nOB2S

Embedding concrete struct type in a struct, then marshal it:
https://go.dev/play/p/Wwf-DztRIlO

What did you see happen?

Output of first Playground link (https://go.dev/play/p/SBfpU8nOB2S):

<animal xmlns="urn:whatever">
    <Animal>
        <sound>Woof!</sound>
    </Animal>
</animal>

Output of second Playground link (https://go.dev/play/p/Wwf-DztRIlO):

<animal xmlns="urn:whatever">
    <sound>Woof!</sound>
</animal>

What did you expect to see?

I expected to get second output in both first and second Playground links.

According to the encoding/xml documentation, it says this two things:

https://pkg.go.dev/encoding/xml#Marshal

  • an anonymous struct field is handled as if the fields of its value were part of the outer struct.

Marshal handles an interface value by marshaling the value it contains or, if the interface value is nil, by writing nothing.

So it should know that the interface value is a struct and is embedded, so it should treat the inner struct values as if it were part of the outer struct (basically accomplishing the second output)

Metadata

Metadata

Assignees

No one assigned

    Labels

    DocumentationIssues describing a change to documentation.NeedsFixThe path to resolution is known, but the work has not been done.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions