7

The xml file consists of two elements. Those elements have the same structure except for one element name. I tried to set a value to the XMLName property, but that didn't work.

Xml:

<!-- first element -->
<PERSON>
  <ELEM1>...</ELEM1>
  <ELEM2>...</ELEM2>
  <ELEM3>...</ELEM3>
  <ELEM4>...</ELEM4>
</PERSON>


<!-- second element -->
<SENDER>
  <ELEM1>...</ELEM1>
  <ELEM2>...</ELEM2>
  <ELEM3>...</ELEM3>
  <ELEM4>...</ELEM4>
</SENDER>

Is it possible to define a struct such that the element name is dynamic?

type Person struct {
    XMLName string `xml:"???"` // How make this dynamic?
    e1 string `xml:"ELEM1"`
    e2 string `xml:"ELEM2"`
    e3 string `xml:"ELEM3"`
    e4 string `xml:"ELEM4"`
}
Community
  • 1
  • 1
Kiril
  • 6,009
  • 13
  • 57
  • 77

2 Answers2

10

In the documentation, it says that the XMLName field must be of type xml.Name.

type Person struct {
    XMLName xml.Name
    E1 string `xml:"ELEM1"`
    // ...
}

Set the element name via the Local field of xml.Name:

person := Person { 
    XMLName: xml.Name { Local: "Person" },
    // ...
}

(Also, E1 - E4 must be exported in order to be included in the XML output).

Playground example: http://play.golang.org/p/bzSutFF9Bo

lnmx
  • 10,846
  • 3
  • 40
  • 36
  • Ah, missed the part about using xml.Name instead of string. Thanks for the example! – Kiril Nov 11 '14 at 14:55
  • Can you show an example of the opposite direction? How would you get the xml source into the struct? – Kiril Nov 11 '14 at 16:14
  • 2
    The same XMLName field works with xml.Unmarshal: http://play.golang.org/p/8-uDgUHVlg – lnmx Nov 11 '14 at 16:37
  • Ok, that works for me, too. But what I can't get to work is to marshal a slice and the unmarshal it back: http://play.golang.org/p/7uxsuMnGxW Am I missing something? – Kiril Nov 11 '14 at 19:15
  • 1
    I think you need a parent XML element (and an enclosing struct) to encode/decode a slice of values. See http://play.golang.org/p/hJLJZP-jcH (also note the `",any"` tag). – lnmx Nov 11 '14 at 19:32
3

I found a lighter solution for this case where you only need to set the struct tag for XMLName field like this:

type Person struct {
    XMLName xml.Name `xml:"Person"`
    E1 string        `xml:"ELEM1"`
    // ...
}
gandarez
  • 2,609
  • 4
  • 34
  • 47