encoding/xml: missing nested namespace not handled
anacrolix opened this issue · 21 comments
Nested XML namespaces aren't marshalled correctly. Setting an element namespace at the default level as Go does, implicitly sets nested elements to the same namespace if they don't override it. <a xmlns="b"><c/></a> The namespace of c, is b. However marshalling from Go data structures in which the object corresponding to c above has no namespace set should give <a xmlns="b"><c xmlns=""/></a> The usual way to deal with this is to use namespace prefixes, but I don't think that's a requirement.
I've created an example: http://play.golang.org/p/5zDgqtC3ra The output is currently: 2009/11/10 23:00:00 "b" == "b" 2009/11/10 23:00:00 "" == "" 2009/11/10 23:00:00 "<A xmlns=\"b\"><C></C></A>" != "<A xmlns=\"b\"><C xmlns=\"\"></C></A>" 2009/11/10 23:00:00 "b" == "b" 2009/11/10 23:00:00 "b" != "" If you read the play source, you'll observe that the namespace of "" on element C has been lost when marshalling. When unmarshalling what Go currently produces, it no longer has "" for C's namespace as a result. This is incorrect, see: http://stackoverflow.com/questions/2193220/xml-namespace-defaulting-inheritance http://www.w3.org/TR/REC-xml-names/#scoping-defaulting http://www.w3.org/TR/xml-names/#defaulting The impact this has on programs using XML, is that they don't reset the default namespace for nested elements when marshalling. Here's some downstream bugs that result from this: https://bitbucket.org/anacrolix/dms/issue/25/get-soap-responses-to-work-with-upnp https://bitbucket.org/anacrolix/dms/issue/19/samsung-doesnt-like-response-to
CL https://golang.org/cl/66850043 references this issue.
Alternate CL at https://golang.org/cl/93320043. Leaving final decision for 1.4.
Labels changed: added release-go1.4, removed release-go1.3maybe.
Is this related to or the same bug as: 'Golang XML unmarshalling issue: local name collisions fail' https://stackoverflow.com/questions/24870309/golang-xml-unmarshalling-issue-local-name-collisions-fail/ I am asking as I am trying to figure out if I should submit a bug for my issue.
I'm writing an RPM manager using GO and I ended up with this problem too. The XML file primary.xml provided by any RPM repository uses "rpm:entry" and others tags with the "rpm" as namespace prefix. It took me two days until I figured out It's a bug. Well, I did some string.replace and it works, but not as good as xml.Marshal.
CL https://golang.org/cl/12570 mentions this issue.
Can I help with issue ?
Change https://golang.org/cl/108796 mentions this issue: encoding/xml fix overriding by empty namespace
The namespace defined by xmlns="value" can be overridden in every included tag including by the empty namespace xmlns="". Empty namespace is not authorized with a prefix (xmlns:ns="") and a related fix has been submitted (#8068) .
Method to calculate indent of XML handles depth of tag and its associated namespace. The fix leaves the method active even when no indent is required.
An XMLName field in a struct means that namespace must be enforced even if empty. This occurs only on an inner tag as an overwrite of any non-empty namespace of its outer tag.
To obtain the xmlns="" required, an attribute is added.
A typo was also fixed as the attribute was writing the tag space and not the attribute space. If no namespace is active, nothing is written.
A specific test is added which derives from the submitted example.
Change https://golang.org/cl/109855 mentions this issue: encoding/xml : Fixes to enforce XML namespace standard
Change https://go.dev/cl/466295 mentions this issue: encoding/xml: only overriding by empty namespace when no new name dec…