New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

encoding/xml: cannot marshal self-closing tag #21399

Open
halfcrazy opened this Issue Aug 11, 2017 · 16 comments

Comments

Projects
None yet
10 participants
@halfcrazy

halfcrazy commented Aug 11, 2017

Please answer these questions before submitting your issue. Thanks!

What version of Go are you using (go version)?

go version go1.8.3 darwin/amd64

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/xxx/.go:/Users/xxx/workspace/goproject"
GORACE=""
GOROOT="/usr/local/Cellar/go/1.8.3/libexec"
GOTOOLDIR="/usr/local/Cellar/go/1.8.3/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/53/r61bh2fj1hg9n0w03fs__7kc0000gn/T/go-build440341166=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"

What did you do?

I want to marshal a xml struct which has a self-closing tag field. After looking up in golang doc, there isn't an official support. In google group they use string.Replace, it's ugly. It seems we could write marshal func for the custom struct, by i'm willing to see an official support like

	type Person struct {
		XMLName   xml.Name `xml:"person"`
		Id        int      `xml:"id,attr"`
		FirstName string   `xml:"name>first"`
		LastName  string   `xml:"name>last"`
		Age       int      `xml:"age"`
		Height    float32  `xml:"height,omitempty"`
		Married   bool
		Address
		Comment string `xml:",comment"`
		Balabala string `xml:"balabala,allowempty"`  // i want something like this
	}

In xml standard, a self-closing tag is permitted.
https://www.w3.org/TR/REC-xml/#dt-empty

And empty-element tag should be used, and should only be used, for elements which are declared EMPTY.
https://www.w3.org/TR/REC-xml/#d0e2480

@Manishearth

This comment has been minimized.

Contributor

Manishearth commented Aug 29, 2017

I like this idea; though i suspect the community will have to agree on it (and also the naming of the tag)

However, I whipped up a quick implementation at https://go-review.googlesource.com/59830 .

I'll polish it up and add tests if this proposal actually goes through.

@gopherbot

This comment has been minimized.

gopherbot commented Aug 29, 2017

Change https://golang.org/cl/59830 mentions this issue: encoding/xml: add 'allowempty' tag for self-closing XML tags

@ianlancetaylor ianlancetaylor added this to the Go1.10 milestone Aug 29, 2017

@ianlancetaylor

This comment has been minimized.

Contributor

ianlancetaylor commented Aug 29, 2017

CC @rsc XML suggestion.

@SamWhited

This comment has been minimized.

Member

SamWhited commented Aug 29, 2017

Change https://golang.org/cl/59830 mentions this issue: encoding/xml: add 'allowempty' tag for self-closing XML tags

The proposed patch only works for marshaling structs. What if we're using the EncodeToken method and write a StartElement immediately followed by its corresponding EndElement? If this ends up being desired and it were an option on the Encoder instead it would work in both places (although it would be global for all tags, not local to specific struct fields, but that seems more desriable to me).

@Manishearth

This comment has been minimized.

Contributor

Manishearth commented Aug 29, 2017

We still need the ability to output non-selfclosing pairs of tags. The idea is to give the user the option to make certain fields self closing, not to do that for all fields.

@Manishearth

This comment has been minimized.

Contributor

Manishearth commented Aug 29, 2017

Oh, I see, you're suggesting this be global. Hm. I don't really like the idea of making this a global change, but we could also make it an option on the marshaler.

@SamWhited

This comment has been minimized.

Member

SamWhited commented Oct 2, 2017

I don't really like the idea of making this a global change

Is there a benefit to only doing this for some elements and not for others?

@Manishearth

This comment has been minimized.

Contributor

Manishearth commented Oct 2, 2017

For the same reason this bug exists in the first place; not all XML parsers handle this correctly and I wanted maximum flexibility.

I'm fine with doing it the other way though.

@SamWhited

This comment has been minimized.

Member

SamWhited commented Oct 2, 2017

not all XML parsers handle this correctly and I wanted maximum flexibility

If a parser did not handle this you couldn't mix the two anyways, you'd just have to turn it on or off entirely to make sure that parser would work.

In case there's confusion, I'm not suggesting that we always do self-closing tags or non-self-closing tags, but that an individual *Encoder should be configurable to do one or the other.

@Manishearth

This comment has been minimized.

Contributor

Manishearth commented Oct 2, 2017

fair. I'll change the patches. Should/can I tag you for review?

@SamWhited

This comment has been minimized.

Member

SamWhited commented Oct 2, 2017

fair. I'll change the patches. Should/can I tag you for review?

I don't have +2 permissions, but I'm happy to run trybots and provide feedback (also, setting this on the Encoder is my suggestion, but I don't actually have any authority here, so grain of salt until rsc or someone replies :) )

@dnaeon

This comment has been minimized.

dnaeon commented Nov 18, 2017

Can we expect this to be implemented in Go 1.10?

Currently we have a Go library, that needs to communicate with a remote API endpoint, which can only understand empty XML elements with self-closing tags.

With the current implementation of XML package we are not able to use Go in order to communicate with that API endpoint. I realize that this is an issue of the remote side by not supporting both ways of specifying empty elements, but having the option to define how empty elements are defined in Go structs would be very useful and would allow us to overcome such edge cases.

Thanks,
Marin

@rsc rsc modified the milestones: Go1.10, Go1.11 Nov 22, 2017

@rsc

This comment has been minimized.

Contributor

rsc commented Nov 22, 2017

Sorry, but we're not going to get to this for Go 1.10.

@iWdGo

This comment has been minimized.

Contributor

iWdGo commented Mar 28, 2018

The current behaviour of documented tag "omitempty" allows the following workaround.
AllowEmpty string `xml:"allowempty>doesnotmatter,omitempty"'
will be marshalled as
<allowempty></allowempty>

@cfstras

This comment has been minimized.

cfstras commented Apr 24, 2018

@iWdGo how does this solve the original question?

The desire is to produce either
<tag /> or <tag>notempty</tag>. Not <tag></tag>.

@iWdGo

This comment has been minimized.

Contributor

iWdGo commented Apr 24, 2018

The answer was focused on the suggested additional tag. A medium fix is required to use self-closing tags. If implemented, it would not be optional without breaking Go 1 promise. #9519 and #8167 have the same constraint.

@bradfitz bradfitz modified the milestones: Go1.11, Go1.12 Jun 13, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment