diff --git a/xsdgen/testdata/redundant-union.go.golden b/xsdgen/testdata/redundant-union.go.golden
new file mode 100644
index 0000000..33a37b4
--- /dev/null
+++ b/xsdgen/testdata/redundant-union.go.golden
@@ -0,0 +1,18 @@
+// Code generated by xsdgen.test. DO NOT EDIT.
+
+package ws
+
+import "encoding/xml"
+
+// May be one of A, B, C
+type EnumType string
+
+const (
+ EnumType_A EnumType = "A"
+ EnumType_B EnumType = "B"
+ EnumType_C EnumType = "C"
+)
+
+type Type1 struct {
+ Elem []EnumType `xml:"Elem,omitempty"`
+}
diff --git a/xsdgen/testdata/redundant-union.xsd b/xsdgen/testdata/redundant-union.xsd
new file mode 100644
index 0000000..cd28300
--- /dev/null
+++ b/xsdgen/testdata/redundant-union.xsd
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xsdgen/xsdgen.go b/xsdgen/xsdgen.go
index 0604c4d..af41607 100644
--- a/xsdgen/xsdgen.go
+++ b/xsdgen/xsdgen.go
@@ -402,6 +402,54 @@ func dedup(types []xsd.Type) (unique []xsd.Type) {
return unique
}
+// for now, bustUnion only resolves simple cases like a union of a builtin and an enum of the same builtin, e.g. in
+// this case redundantUnionType will be replaced with enumType
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+func (cfg *Config) bustUnion(t *xsd.SimpleType) xsd.Type {
+ var underlying xsd.Type
+ var actual xsd.Type
+ for _, member := range t.Union {
+ switch ut := member.(type) {
+ case xsd.Builtin:
+ if underlying != nil && underlying != ut {
+ // can't simplify
+ return t
+ }
+ underlying = ut
+ case *xsd.SimpleType:
+ base := xsd.Base(ut)
+ if underlying != nil && underlying != ut {
+ // can't simplify
+ return t
+ }
+ if actual != nil && actual != ut {
+ // TODO: can we simplify this case?
+ return t
+ }
+ underlying = base
+ actual = ut
+ default:
+ // TODO: handle more union member types
+ return t
+ }
+ }
+
+ if actual != nil {
+ return actual
+ }
+ return underlying
+}
+
func (cfg *Config) flatten1(t xsd.Type, push func(xsd.Type), depth int) xsd.Type {
const maxDepth = 1000
if depth > maxDepth {
@@ -414,7 +462,12 @@ func (cfg *Config) flatten1(t xsd.Type, push func(xsd.Type), depth int) xsd.Type
base, builtin xsd.Type
ok bool
)
- // TODO: handle list/union types
+ // TODO: handle list types
+
+ if len(t.Union) > 0 {
+ return cfg.bustUnion(t)
+ }
+
for base = xsd.Base(t); base != nil; base = xsd.Base(base) {
if builtin, ok = base.(xsd.Builtin); ok {
break