hooklift / gowsdl

WSDL2Go code generation as well as its SOAP proxy
Mozilla Public License 2.0
1.14k stars 390 forks source link

Referenced elements of type "xs:dateTime" et al. cannot be marshaled #221

Closed w65536 closed 2 years ago

w65536 commented 2 years ago

This problem affects elements of types xs:dateTime, xs:time and xs:date when they are being referenced. This generates a new type definition like so:

type MyDateTime soap.XSDDateTime

The new type MyDateTime cannot be marshaled/unmarshaled because it does not satisfy the xml.Marshaler and xml.Unmarshaler interfaces. Only the underlying types soap.XSDDateTime, soap.XSDDate and soap.XSDTime do satisfy those interfaces.

It is interesting to note that the same problem is not present for referenced attributes. The traverser does resolve the attribute refs in place: https://github.com/hooklift/gowsdl/blob/9e1cc9a7689230f4da66504844af631a0c4767cc/traverser.go#L66-L76

For illustration purposes here is an example with referenced elements and attributes. This XSD definition:

<!-- complex type with references -->
<s:complexType name="myComplexType">
  <s:sequence>
    <s:element ref="myDateTime"/>
  </s:sequence>
  <s:attribute ref="tns:myBaseAttribute"/>
</s:complexType>
<!-- referenced attribute -->
<s:attribute name="myBaseAttribute">
  <s:simpleType>
    <s:restriction base="s:dateTime">
    </s:restriction>
  </s:simpleType>
</s:attribute>
<!-- referenced element -->
<s:element name="myDateTime" type="s:dateTime">
  <s:annotation>
    <s:documentation>The date and time when it occurred</s:documentation>
  </s:annotation>
</s:element>

results in following code generation:

type MyDateTime soap.XSDDateTime

type MyComplexType struct {
    XMLName xml.Name `xml:"http://www.example.com/webservices/ myComplexType"`

    MyDateTime *MyDateTime `xml:"myDateTime,omitempty" json:"myDateTime,omitempty"`

    MyBaseAttribute soap.XSDDateTime `xml:"myBaseAttribute,attr,omitempty" json:"myBaseAttribute,omitempty"`
}

The attribute type is resolved in place while the element has generated an additional type definition.

I can see two approaches to solve this issue:

  1. Generate xml.Marshaler and xml.Unmarshaler interface methods for the generated types as wrappers around the same methods of the underlying types soap.XSDDateTime, soap.XSDDate or soap.XSDTime
  2. Enhance the traverser to also have the capability of resolving element references in place. I am however not familiar with the subtleties of the hierarchical complexity of the various elements and use cases involved. Those are obviously way beyond the particular date/time types actually affected by this problem.
w65536 commented 2 years ago

I have proposed a pull request #222 adopting the first solution approach as described above.