Directly against indirectly nested structures

There is an example in the Go documentation for xml: Unmarshal that cancels this xml

<Person> <FullName>Grace R. Emlin</FullName> <Company>Example Inc.</Company> <Email where="home"> <Addr> gre@example.com </Addr> </Email> <Email where='work'> <Addr> gre@work.com </Addr> </Email> <Group> <Value>Friends</Value> <Value>Squash</Value> </Group> <City>Hanga Roa</City> <State>Easter Island</State> </Person> 

using these structures

  type Address struct { City, State string } type Result struct { XMLName xml.Name `xml:"Person"` Name string `xml:"FullName"` Phone string Email []Email Groups []string `xml:"Group>Value"` Address } 

Note that Result contains a link to a separately defined Address . Obviously this code works.


When I try to unmount this xml

 <C> <D> <E>Fred</E> <F>42</F> </D> </C> 

using these structures

 type D struct { E string F int } type C struct { // Compiles OK but result empty. D } 

I get empty results {{ 0}} . However, the structure below works fine, producing {{Fred 42}}

 type C struct { // This works. D struct { E string F int } } 

See an example of a playground .

Did I miss some subtle points about structures?

+5
source share
1 answer

When you do this:

 type C struct { D } 

This is called embedding ( D is an anonymous field or an embedded field). You can think of it as if the fields (and methods) of the built-in type became part of the type of embedding (they get promoted). Therefore, in this case, the CE and CF record is “legal”.

When you do:

 type C struct { D struct { E string F int } } 

This is not an attachment (or "nesting"). Here D is a “regular” field called a type C field. D is the name of the field, followed by the anonymous type literal , the type of the field. There is no right to write CE and CF , only CDE and CDF . And this is the correct display of the XML structure you are trying to decouple, so this works (try on the Go Playground ).

Please note that if you change the attachment to the regular field, it will also work (try on Go Playground ):

 type C struct { DD } 

Also note that you can skip the whole construction of the D shell if you specify XML element paths in field tags:

 type C struct { E string `xml:"D>E"` F int `xml:"D>F"` } 

Try it on the go playground .

+5
source

Source: https://habr.com/ru/post/1264790/


All Articles