-
Notifications
You must be signed in to change notification settings - Fork 18k
encoding/xml: not marshalling nil pointer in struct without ",omitempty" #53408
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
Comments
please include example code that demonstrates the issue |
Pleaes read the docs - they do state this quite clearly:
|
Well, to me this is not clear, it's surprising and unnecessary. If you read the docs further, it talks about how it handles structs below the first paragraph which explains the start of the marshalling (imho). For struct with pointers or interfaces, the ",omitempty" option is useless otherwise. And it is different than MarshalJSON. And there is no way working around this issue. So please re-open the ticket and let's discuss this further. An example can be found here: https://goplay.space/#1ipwnPTcOwh Since the current behaviour can be restored by using ",omitempty" on affected struct fields, I think this is a patch to consider.
And I think it is ok that the documentation says, it ignores NIL interface and NIL pointer when it STARTS MARSHALLING (thus the text at the beginning), but further down when you talk about how structs and struct tags are handled we read this:
|
If you think the docs are confusing, there's always the option of sending a patch to make them easier to understand. In my brief skim of the docs, I didn't see a clear way to do that. As for changing the behavior - unfortunately we cannot change documented behavior due to https://go.dev/doc/go1compat. Supporting the behavior that you want would require either custom code (like you describe) or new API like an option, for which a detailed proposal should be filed instead: https://github.com/golang/proposal |
To me the docs are pretty clear and I see the current implementation at fault. I am not happy with the way it works at the moment. And it happened in the past that Stdlib feature were refined / matched with the docs. And since the old behaviour can easily be achieved by using ",omitempty", I don't see such a change breaking the promise (which is more about the language itself and not some struct field info interpretation!). So please re-consider a fix for this in an upcoming version of Go. I am happy to send in a patch which fixes this issue. As for the doc change, you can simply NOT TALK about "nil pointer" or "interface values" in the ",omitempty" explanation (which is a copy from the MarshalJSON behaviour), as it has no effect whatsoever anyways...
|
I'm going to reopen this for now because you clearly think that there's a bug to be fixed, but I honestly cannot understand how we can change the existing documented behavior without breaking existing programs. Perhaps someone else can understand what I don't seem to be able to. At the same time, I would ask you to refrain from using bold and all-capital text - it comes off as unnecessarily aggressive :) I understand you may be frustrated, but there's no need to direct that at the maintainers. |
Next time please actually use the issue template. |
Thanks for reopening. The bold text was merely for people how skim through long texts, I personally find it much easier to read as it gives the text more structure. And I can understand that you think the docs are clear, but to me they were not (maybe because I would assume the xml encoding to match the json encoding as closely as possible). The first paragraph talks about the entry point of the marshalling where "nil pointer and interface" are ignored and that is ok. It's the only option we have when we start the encoding. But once we encode struct values it makes a lot of sense to allow ",omitempty" to have an effect on "nil pointer and interface" value. As for breaking existing implementations, since the change would only produce more XML, the practical impact will be close to zero. Empty tags are simply ignored and semantically the XML is the same as it expresses the same thing, just with a little more information. |
Nil pointer would render to 0 bytes.
I updated my example https://goplay.space/#c8ojsSu5Cp5 |
That can't be correct, change the field to a |
Why does that matter? What matters is that I can steer the encoder to do what is desired using ",omitempty". If it's nil and "omitempty" is there, we omit the element, if not, we output the element with no content. Currently we do not know if the struct has B or not at all. And that is the problem for my use case. |
That would break existing code, code that currently skips the output for a From https://stackoverflow.com/questions/774192/what-is-the-correct-way-to-represent-null-xml-elements , XML has no standard concept of null that is portable across domains. While unfortunate, at this is infeasible to change, and has well defined escape hatch for user code that wants a different behavior (implement |
I respect your unfortunate decision. Users could have restored the current behaviour using ",omitempty". Anyways, I do not want to give up easily, so I will suggest a new tag for struct field ",notomitempty" or so, to get the behaviour I need. Please consider updating the docs at least, see above for a suggestion. "omitempty" talks about "nil pointer and interface" which is clearly not happening and as such a bug in the docs. |
The xml marshaler skips nil pointers in struct values even if "omitempty" is not set. This is not what I would expect from encoding. I expect that behaviour if I set ",omitempty" on the struct field, but not without.
The problem is in the stdlib where this code returns nil and is not encoding a value if it is a nil pointer. This is different from how encoding/json behaves where "nil" is encoded into "null" if not ",omitempty" is set.
Documentation https://pkg.go.dev/encoding/xml says this:
From this I understand that "any nil pointer or interface value" WITHOUT the ",omitempty" is NOT omitted during marshalling...
The text was updated successfully, but these errors were encountered: