gnewton / chidley

Convert XML to Go structs / XML to JSON
Apache License 2.0
273 stars 35 forks source link

Double use of field name Text #22

Closed fawick closed 6 years ago

fawick commented 7 years ago

In case an XML element has CharData as well as (possibly multiple) sub-elements with the name Text the resulting Go struct will have two fields called Text, e.g.

type Foo struct {
    Text []*Text `xml:"text,omitempty" json:"text,omitempty"`
    Text string `xml:",chardata" json:",omitempty"`
}
fawick commented 7 years ago

How about using CharData instead of Text for the fixed name? Or one could use a cmdline flag for that, with Text being the default for backwards compatibility.

gnewton commented 7 years ago

chidley out of the box does not exhibit the issue you have identified.

Modifying slightly an example from the README

<people>
  <person>
    <name>bill</name>
    <age>37</age>
    <married>true</married>
  </person>
  <person>
    <name>sarah</name>
    <age>24<text>foobar</text></age>
    <married>false</married>
  </person>
</people>

Running chidley gives:

$ chidley persons.xml

type ChiChidleyRoot314159 struct {
    ChiPeople *ChiPeople `xml:" people,omitempty" json:"people,omitempty"`
}

type ChiAge struct {
    ChiText *ChiText `xml:" text,omitempty" json:"text,omitempty"`
    Text string `xml:",chardata" json:",omitempty"`
}

type ChiMarried struct {
    Text string `xml:",chardata" json:",omitempty"`
}

type ChiName struct {
    Text string `xml:",chardata" json:",omitempty"`
}

type ChiPeople struct {
    ChiPerson []*ChiPerson `xml:" person,omitempty" json:"person,omitempty"`
}

type ChiPerson struct {
    ChiAge *ChiAge `xml:" age,omitempty" json:"age,omitempty"`
    ChiMarried *ChiMarried `xml:" married,omitempty" json:"married,omitempty"`
    ChiName *ChiName `xml:" name,omitempty" json:"name,omitempty"`
}

type ChiText struct {
    Text string `xml:",chardata" json:",omitempty"`
}

However, if you do not want to use the default prefix mode, and set the prefix to be blank, then the issue you have identified does show up:

$ chidley -e "" persons.xml

type ChidleyRoot314159 struct {
    People *People `xml:" people,omitempty" json:"people,omitempty"`
}

type Age struct {
    Text *Text `xml:" text,omitempty" json:"text,omitempty"`
    Text string `xml:",chardata" json:",omitempty"`
}

type Married struct {
    Text string `xml:",chardata" json:",omitempty"`
}

type Name struct {
    Text string `xml:",chardata" json:",omitempty"`
}

type People struct {
    Person []*Person `xml:" person,omitempty" json:"person,omitempty"`
}

type Person struct {
    Age *Age `xml:" age,omitempty" json:"age,omitempty"`
    Married *Married `xml:" married,omitempty" json:"married,omitempty"`
    Name *Name `xml:" name,omitempty" json:"name,omitempty"`
}

type Text struct {
    Text string `xml:",chardata" json:",omitempty"`
}

The above is clearly wrong and won't compile.

The default prefix mode was created to avoid name conflicts, internally to the structs chidley produces and with other structs that might be extant in a particular program.

I don't see the change you are suggesting as necessary, but I don't see any harm in it either. If you do not like any prefix to your struct names, then this change is needed.

I will take a look at your PR tomorrow.

Thanks, Glen

fawick commented 7 years ago

Oh yes, you are absolutely right, I should have mentioned that vital piece of information. I was running with -e "". Stupid me!

gnewton commented 6 years ago

The latest version supports this. Use the -M argument to set.