Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xsdgen on tableau api 3.6 xsd fails to generate #99

Open
jaby opened this issue Mar 5, 2020 · 2 comments
Open

xsdgen on tableau api 3.6 xsd fails to generate #99

jaby opened this issue Mar 5, 2020 · 2 comments

Comments

@jaby
Copy link

jaby commented Mar 5, 2020

When trying to generate the schema structures for the Tableau 3.6. api, the generation is invalid.

Full xsd is available here: https://help.tableau.com/samples/en-us/rest_api/ts-api_3_6.xsd

More specifically the Lastday in this monthDay attribute is generated as 'type string', while it should have been 'type LastDay string'

    <xs:complexType name="intervalType">
        <xs:attribute name="minutes">
            <xs:simpleType>
                <xs:restriction base="xs:nonNegativeInteger">
                    <xs:enumeration value="15" />
                    <xs:enumeration value="30" />
                </xs:restriction>
            </xs:simpleType>
        </xs:attribute>
        <xs:attribute name="hours">
            <xs:simpleType>
                <xs:restriction base="xs:nonNegativeInteger">
                    <xs:enumeration value="1" />
                    <xs:enumeration value="2" />
                    <xs:enumeration value="4" />
                    <xs:enumeration value="6" />
                    <xs:enumeration value="8" />
                    <xs:enumeration value="12" />
                </xs:restriction>
            </xs:simpleType>
        </xs:attribute>
        <xs:attribute name="weekDay" >
            <xs:simpleType>
                <xs:restriction base="xs:string">
                    <xs:enumeration value="Monday" />
                    <xs:enumeration value="Tuesday" />
                    <xs:enumeration value="Wednesday" />
                    <xs:enumeration value="Thursday" />
                    <xs:enumeration value="Friday" />
                    <xs:enumeration value="Saturday" />
                    <xs:enumeration value="Sunday" />
                </xs:restriction>
            </xs:simpleType>
        </xs:attribute>
        <xs:attribute name="monthDay" >
            <xs:simpleType>
                <xs:union>
                    <xs:simpleType>
                        <xs:restriction base="xs:integer">
                            <xs:minInclusive value="1" />
                            <xs:maxInclusive value="31" />
                        </xs:restriction>
                    </xs:simpleType>
                    <xs:simpleType>
                        <xs:restriction base="xs:string">
                            <xs:enumeration value="LastDay" />
                        </xs:restriction>
                    </xs:simpleType>
                </xs:union>
            </xs:simpleType>
        </xs:attribute>
    </xs:complexType>

I suspect a problem with the union combining 2 different datatypes 'xs:integer' and 'xs:string', but I have not investigated in detail. Other union combining 'xs:integer' with 'xs:integer' works fine.

Currently using this workaround, as there seems to be only 1 xsdSimpleType with a blanc name:

func main() {
	var cfg xsdgen.Config

	cfg.Option(
		xsdgen.IgnoreAttributes("href", "offset"),
		xsdgen.Replace(`[._ \s-]`, ""),
		xsdgen.PackageName("ws"),
		xsdgen.HandleSOAPArrayType(),
		xsdgen.SOAPArrayAsSlice(),
		xsdgen.UseFieldNames(),

		xsdgen.ProcessTypes(func(s xsd.Schema, t xsd.Type) xsd.Type {
			switch t.(type) {
			case *xsd.SimpleType:
				// workaround for the invalid generation of LastDay type,
				st := t.(*xsd.SimpleType)
				if st.Name.Local == "" {
					st.Name.Local = "LastDay"
				}
			}
			return t
		}),
	)
	if err := cfg.GenCLI(os.Args[1:]...); err != nil {
		log.Fatal(err)
	}
}
@droyo
Copy link
Owner

droyo commented Mar 21, 2020

I haven't looked to deeply into this, but I looked at the output from an xsdgen run. Looking at the schema, I would expect this

    type MonthDay string

which is in the output. But this

    // May be one of LastDay
    type  string

shouldn't be there at all. That's a bug. It shouldn't be type LastDay string either, "LastDay" is a potential value for the type, not the type itself. The type itself is anonymous, so if anything it should be

    type AnonX string

However, there should be some passes that remove anonymous types that can just be put directly in struct definitions, so that shouldn't exist either. The xsdgen package does not handle union types well. In an ideal world, I'd like to have something like this:

    type MonthDay interface {
      xsdUnionMonthDay()
    }
    
    // range 1-31
    type MonthDay1 int
    func (MonthDay1) xsdUnionMonthDay() {}
    
    // may be one of LastDay
    type MonthDay2 string
    func (MonthDay1) xsdUnionMonthDay() {}

Even that is a little ugly.

@nikolawannabe
Copy link

I also saw this issue when generating code from the ONIX 3.0 spec: https://www.editeur.org/93/Release-3.0-Downloads/

Most types were generated as type string instead of their (existing but not used) more complex types and a lot of anonymous types were left unreferenced. I went through and manually repaired about 1k worth of references to use their more specific type but I'm certain this could be done in the tool if it was clear on how it was supposed to happen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants