Skip to content

Feature/add namespace #109

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

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
14 changes: 14 additions & 0 deletions xsdgen/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ type Config struct {
// if populated, only types that are true in this map
// will be selected.
allowTypes map[xml.Name]bool

//True for adding namespace to the struct
addNamespace bool
}

type typeTransform func(xsd.Schema, xsd.Type) xsd.Type
Expand Down Expand Up @@ -76,6 +79,7 @@ var DefaultOptions = []Option{
HandleSOAPArrayType(),
SOAPArrayAsSlice(),
UseFieldNames(),
AddNamespace(false),
}

// The Namespaces option configures the code generation process
Expand Down Expand Up @@ -344,6 +348,15 @@ func useFieldNames(s xsd.Schema, t xsd.Type) xsd.Type {
return t
}

// AddNamespace to the generated structs
func AddNamespace(addNamespace bool) Option {
return func(cfg *Config) Option {
prev := cfg.addNamespace
cfg.addNamespace = addNamespace
return AddNamespace(prev)
}
}

// ProcessTypes allows for users to make arbitrary changes to a type before
// Go source code is generated.
func ProcessTypes(fn func(xsd.Schema, xsd.Type) xsd.Type) Option {
Expand Down Expand Up @@ -409,6 +422,7 @@ func SOAPArrayAsSlice() Option {
}
}


func (cfg *Config) filterFields(t *xsd.ComplexType) ([]xsd.Attribute, []xsd.Element) {
var (
elements []xsd.Element
Expand Down
40 changes: 40 additions & 0 deletions xsdgen/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -356,3 +356,43 @@ func ExampleUseFieldNames() {
// }

}

func ExampleAddNamespace() {
doc := xsdfile(`
<complexType name="library">
<sequence>
<element name="book" maxOccurs="1">
<complexType>
<all>
<element name="title" type="xs:string" />
<element name="author" type="xs:string" />
</all>
</complexType>
</element>
</sequence>
</complexType>`)

var cfg xsdgen.Config
cfg.Option(xsdgen.AddNamespace(true))

out, err := cfg.GenSource(doc)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", out)

// Output: // Code generated by xsdgen.test. DO NOT EDIT.
//
// package ws
//
// type Book struct {
// XMLNs string `xml:"xmlns:tns,attr,omitempty"`
// Title string `xml:"tns:title"`
// Author string `xml:"tns:author"`
// }

// type Library struct {
// XmlNS string `xml:"xmlns:tns,attr,omitempty"`
// Book Book `xml:"tns:book"`
// }
}
68 changes: 55 additions & 13 deletions xsdgen/xsdgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ func (cfg *Config) expandComplexTypes(types []xsd.Type) []xsd.Type {
for _, el := range b.Elements {
if _, ok := shadowedElements[el.Name]; !ok {
elements = append(elements, el)

} else {
cfg.debugf("complexType %s: extended element %s is overrided",
c.Name.Local, el.Name.Local)
Expand Down Expand Up @@ -522,6 +523,17 @@ func (cfg *Config) flatten1(t xsd.Type, push func(xsd.Type), depth int) xsd.Type
panic(fmt.Errorf("unexpected %T(%s %s)", t, xsd.XMLName(t).Space, xsd.XMLName(t).Local))
}

func addNamespace(t *xsd.ComplexType) {
if t.Elements[0].Name.Local != "XMLNs" {
namespace := make([]xsd.Element, 1)
namespace[0].Name.Local = "XMLNs"
namespace[0].Name.Space = t.Elements[0].Name.Space
namespace[0].Type = xsd.String
namespace[0].Scope = t.Elements[0].Scope
t.Elements = append(namespace, t.Elements...)
}
}

func (cfg *Config) genTypeSpec(t xsd.Type) (result []spec, err error) {
var s []spec
cfg.debugf("generating type spec for %q", xsd.XMLName(t).Local)
Expand All @@ -530,6 +542,9 @@ func (cfg *Config) genTypeSpec(t xsd.Type) (result []spec, err error) {
case *xsd.SimpleType:
s, err = cfg.genSimpleType(t)
case *xsd.ComplexType:
if cfg.addNamespace {
addNamespace(t)
}
s, err = cfg.genComplexType(t)
case xsd.Builtin:
// pass
Expand Down Expand Up @@ -684,7 +699,19 @@ func (cfg *Config) genComplexType(t *xsd.ComplexType) ([]spec, error) {
if el.Nillable || el.Optional {
options = ",omitempty"
}

tag := fmt.Sprintf(`xml:"%s %s%s"`, el.Name.Space, el.Name.Local, options)

if cfg.addNamespace {
prefixLocal := strings.Split(el.Scope.Prefix(el.Name), ":")
tag = fmt.Sprintf(`xml:"%s:%s%s"`, prefixLocal[0], el.Name.Local, options)
}

if el.Name.Local == "XMLNs" {
prefixLocal := strings.Split(el.Scope.Prefix(el.Name), ":")
tag = fmt.Sprintf(`xml:"xmlns:%s,attr,omitempty"`, prefixLocal[0])
}

base, err := cfg.expr(el.Type)
if err != nil {
return nil, fmt.Errorf("%s element %s: %v", t.Name.Local, el.Name.Local, err)
Expand Down Expand Up @@ -778,31 +805,44 @@ func (cfg *Config) genComplexType(t *xsd.ComplexType) ([]spec, error) {
xsdType: t,
helperTypes: helperTypes,
}
if len(overrides) > 0 {
if len(overrides) > 0 || cfg.addNamespace {
unmarshal, marshal, err := cfg.genComplexTypeMethods(t, overrides)
if err != nil {
return result, err
} else {
if unmarshal != nil {
s.methods = append(s.methods, unmarshal)
}
if marshal != nil {
s.methods = append(s.methods, marshal)
}
}
if unmarshal != nil {
s.methods = append(s.methods, unmarshal)
}
if marshal != nil {
s.methods = append(s.methods, marshal)
}

}
result = append(result, s)
return result, nil
}

func (cfg *Config) genComplexTypeMethods(t *xsd.ComplexType, overrides []fieldOverride) (marshal, unmarshal *ast.FuncDecl, err error) {
var data struct {
Overrides []fieldOverride
Type string
Overrides []fieldOverride
Type string
NameSpaces []xml.Name
}
data.Overrides = overrides
data.Type = cfg.public(t.Name)

if cfg.addNamespace {
nameSpace := t.Elements[0].Name.Space
for _, el := range t.Elements {
if el.Name.Space != nameSpace {
var namespace xml.Name
namespace.Space = el.Name.Space
namespace.Local = strings.Title(el.Name.Local)
data.NameSpaces = append(data.NameSpaces, namespace)
}
}
}

unmarshal, err = gen.Func("UnmarshalXML").
Receiver("t *"+data.Type).
Args("d *xml.Decoder", "start xml.StartElement").
Expand Down Expand Up @@ -838,9 +878,6 @@ func (cfg *Config) genComplexTypeMethods(t *xsd.ComplexType, overrides []fieldOv
nonDefaultOverrides = append(nonDefaultOverrides, v)
}
}
if len(nonDefaultOverrides) == 0 {
return nil, unmarshal, nil
}

data.Overrides = nonDefaultOverrides
marshal, err = gen.Func("MarshalXML").
Expand All @@ -856,10 +893,15 @@ func (cfg *Config) genComplexTypeMethods(t *xsd.ComplexType, overrides []fieldOv
{{end -}}
}
layout.T = (*T)(t)

{{- range .Overrides}}
layout.{{.FieldName}} = (*{{.ToType}})(&layout.T.{{.FieldName}})
{{end -}}

{{- range .NameSpaces}}
layout.{{.Local}}.XMLNs = "{{.Space}}"
{{end -}}
//
return e.EncodeElement(layout, start)
`, data).Decl()
return marshal, unmarshal, err
Expand Down