Skip to content

Commit

Permalink
fix: handle empty root elements with names
Browse files Browse the repository at this point in the history
  • Loading branch information
twpayne committed Aug 21, 2024
1 parent 56e6570 commit 053bc5b
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 7 deletions.
2 changes: 1 addition & 1 deletion element.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ FOR:

// writeGoType writes e's Go type to w.
func (e *element) writeGoType(w io.Writer, options *generateOptions, indentPrefix string) error {
if len(e.attrValues) == 0 && len(e.childElements) == 0 {
if len(e.attrValues) == 0 && len(e.childElements) == 0 && (!e.root || !options.namedRoot) {
fmt.Fprintf(w, "%s", e.charDataValue.goType(options))
return nil
}
Expand Down
14 changes: 8 additions & 6 deletions generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ func (g *Generator) Generate() ([]byte, error) {
options.namedTypes = maps.Clone(g.typeElements)
options.simpleTypes = make(map[xml.Name]struct{})
for name, element := range options.namedTypes {
if len(element.attrValues) != 0 || len(element.childElements) != 0 {
if len(element.attrValues) != 0 || len(element.childElements) != 0 || element.root {
continue
}
options.simpleTypes[name] = struct{}{}
Expand Down Expand Up @@ -416,7 +416,7 @@ func (g *Generator) ObserveReader(r io.Reader) error {
if g.modifyDecoderFunc != nil {
g.modifyDecoderFunc(decoder)
}
var rootElement *element
var foundRootElement bool
FOR:
for {
var token xml.Token
Expand All @@ -433,22 +433,24 @@ FOR:
return err
default:
if startElement, ok := token.(xml.StartElement); ok {
var root bool
if !foundRootElement {
foundRootElement = true
root = true
}
name := g.nameFunc(startElement.Name)
if name == (xml.Name{}) {
continue FOR
}
typeElement, ok := g.typeElements[name]
if !ok {
typeElement = newElement(name)
typeElement.root = root
g.typeElements[name] = typeElement
}
if _, ok := g.typeOrder[name]; !ok {
g.typeOrder[name] = options.getOrder()
}
if rootElement == nil {
rootElement = typeElement
rootElement.root = true
}
if err := typeElement.observeChildElement(decoder, startElement, 0, &options); err != nil {
return err
}
Expand Down
32 changes: 32 additions & 0 deletions generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,38 @@ func TestGenerator(t *testing.T) {
`}`,
),
},
{
name: "empty_top_level_named_type",
xmlStr: "<a/>",
options: []xmlstruct.GeneratorOption{
xmlstruct.WithNamedTypes(true),
},
expectedStr: joinLines(
xmlstruct.DefaultHeader,
``,
`package main`,
``,
`type A struct{}`,
),
},
{
name: "empty_top_level_named_root_type",
xmlStr: "<a/>",
options: []xmlstruct.GeneratorOption{
xmlstruct.WithNamedRoot(true),
},
expectedStr: joinLines(
xmlstruct.DefaultHeader,
``,
`package main`,
``,
`import "encoding/xml"`,
``,
`type A struct {`,
"\tXMLName xml.Name `xml:\"a\"`",
`}`,
),
},
} {
tc := tc
t.Run(tc.name, func(t *testing.T) {
Expand Down

0 comments on commit 053bc5b

Please sign in to comment.