Reputation: 8442
I'm parsing XML, and at most every level of the document, there's a description
.
Here's an toy example:
<obj>
<description>outer object</description>
<subobjA>
<description>first kind of subobject</description>
<foo>some goop</foo>
</subobjA>
<subobjB>
<description>second kind of subobject</description>
<bar>some other goop</bar>
</subobjB>
</obj>
This means that every struct involved has an identical Description
member, with an identical tag `xml:"description,omitempty"`
.
Here's functioning code: http://play.golang.org/p/1-co6Qcm8d
I'd rather the Description tags be DRY. The obvious thing to want to do is something like:
type Description string `xml:"description,omitempty"`
and then use the type Description
throughout. However, only struct members can have tags. See http://play.golang.org/p/p83UrhrN4u for what I want to write; it doesn't compile.
One could create a Description
struct and embed it repeatedly, but that adds a layer of indirection when accessing.
Is there another way to go about this?
Upvotes: 5
Views: 246
Reputation: 57757
Embedding a re-factored Description
struct (as you already suggested) is the way to go:
type describable struct{
Description string `xml:"description"`
}
type subobjA struct {
describable
XMLName xml.Name `xml:"subobjA"`
}
type subobjB struct {
describable
XMLName xml.Name `xml:"subobjB"`
}
type obj struct {
XMLName xml.Name `xml:"obj"`
A subobjA
B subobjB
}
The mentioned layer of indirection does not exist. To cite the spec on that topic:
A field or method f of an anonymous field in a struct x is called promoted if x.f is a legal selector that denotes that field or method f.
Promoted fields act like ordinary fields of a struct except that they cannot be used as field names in composite literals of the struct.
So you can do this:
err := xml.Unmarshal([]byte(sampleXml), &sampleObj)
fmt.Println(sampleObj.Description)
fmt.Println(sampleObj.A.Description)
sampleObj.describable.Description
is promoted to be sampleObj.Description
, so no further layer of indirection here.
Upvotes: 4