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

xsd:group generates incorrect output in Go #33

Open
mark-edgeworth opened this issue Oct 27, 2021 · 1 comment
Open

xsd:group generates incorrect output in Go #33

mark-edgeworth opened this issue Oct 27, 2021 · 1 comment

Comments

@mark-edgeworth
Copy link

Description

When a complex type contains an xsd:group reference, the generated
code produces a new struct type for the group rather than expanding
the group content in the original type. Also, no xml:"..." mapping code is
generated, so the group is not parsed from the XML.

I'd prefer it that the group did not yield a new type (as it is just
syntactic sugar inside the schema rather than a real hierarchical
component).

Steps to reproduce the issue:
Using the following test schema:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="qualified" version="0.0.1">
    <!-- Device Properties Group -->
    <xs:group name="MyGroup">
        <xs:sequence>
            <!-- A couple of test elements -->
            <xs:element name="element_1"  type="xs:string"/>
            <xs:element name="element_2" type="xs:string"/>
        </xs:sequence>
    </xs:group>

    <xs:element name="parent_element">
        <xs:complexType>
            <xs:group ref="MyGroup" />
            <xs:attribute name="attr_1" type="xs:string" use="required" />
        </xs:complexType>
    </xs:element>

</xs:schema>

Describe the results you received:

Generated code is

// Code generated by xgen. DO NOT EDIT.

package schema

import (
	"encoding/xml"
)

// MyGroup ...
type MyGroup struct {
	Element1 string
	Element2 string
}

// Parentelement ...
type Parentelement struct {
	XMLName   xml.Name `xml:"parent_element"`
	Attr1Attr string   `xml:"attr_1,attr"`
	MyGroup   *MyGroup
}

Describe the results you expected:
Something like:

// Code generated by xgen. DO NOT EDIT.

package schema

import (
	"encoding/xml"
)

// Parentelement ...
type Parentelement struct {
	XMLName   xml.Name `xml:"parent_element"`
	Attr1Attr string   `xml:"attr_1,attr"`
	Element1 string `xml:"element_1"`
	Element2 string `xml:"element_2"`
}

Output of go version:

go version go1.16.6 darwin/amd64

xgen version or commit ID:

v0.1.0

Environment details (OS, physical, etc.):
MacOS 11.6 Big Sur on Mac Book Pro

@zadeck
Copy link

zadeck commented Feb 6, 2022

I think that the problem is more subtle than this and that the proper solution is not to inline the group.
Consider the following xsd schemata:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="e">
xs:complexType
xs:sequence
<xs:group ref="foo1"/>
<xs:group ref="foo2"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:group name="foo1">
xs:sequence
<xs:element name="foo">
xs:complexType
<xs:attribute name="name" use="required" type="xs:string"/>
<xs:attribute name="value1" use="required" type="xs:double"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:group>
<xs:group name="foo2">
xs:sequence
<xs:element name="foo">
xs:complexType
<xs:attribute name="name" use="required" type="xs:string"/>
<xs:attribute name="value2" use="required" type="xs:integer"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:group>
</xs:schema>

xgen generated the following incorrect code:

// Code generated by xgen. DO NOT EDIT.

package test2

import (
"encoding/xml"
)

// E ...
type E struct {
XMLName xml.Name xml:"e"
Foo1 *Foo1
Foo2 *Foo2
}

// Foo ...
type Foo struct {
XMLName xml.Name xml:"foo"
NameAttr string xml:"name,attr"
Value1Attr float64 xml:"value1,attr"
}

What I think that it really should have done is to use the group name as the name of the structure but put the element name in the attribute for the XMLName.

// Code generated by xgen. DO NOT EDIT.

package test2

import (
"encoding/xml"
)

// E ...
type E struct {
XMLName xml.Name xml:"e"
Foo1 *Foo1
Foo2 *Foo2
}

// Foo1 ...
type Foo1 struct {
XMLName xml.Name xml:"foo"
NameAttr string xml:"name,attr"
Value1Attr float64 xml:"value1,attr"
}

// Foo2 ...
type Foo2 struct {
XMLName xml.Name xml:"foo"
NameAttr string xml:"name,attr"
Value1Attr int xml:"value1,attr"
}

The problem with inlining the group is that if it is referenced many times, you can get a big expansion.

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

2 participants