Code Monkey home page Code Monkey logo

xgen's Introduction

xgen logo


Build Status Code Coverage Go Report Card go.dev Licenses Donate

xgen

Introduction

xgen is a library written in pure Go providing a set of functions that allow you to parse XSD (XML schema definition) files. This library needs Go version 1.10 or later. The full API docs can be seen using go's built-in documentation tool, or online at go.dev.

xgen commands automatically compiles XML schema files into the multi-language type or class declarations code.

Install the command line tool first.

If you're using Go 1.17 and later, installing executables with go install

go install github.com/xuri/xgen/cmd/xgen@latest

If you're using Go 1.16 and earlier, installing executables with go get

go get -u -v github.com/xuri/xgen/cmd/...

The command below will walk on the xsd path and generate Go language struct code under the output directory.

$ xgen -i /path/to/your/xsd -o /path/to/your/output -l Go

Usage:

$ xgen [<flag> ...] <XSD file or directory> ...
   -i <path> Input file path or directory for the XML schema definition
   -o <path> Output file path or directory for the generated code
   -p        Specify the package name
   -l        Specify the language of generated code (Go/C/Java/Rust/TypeScript)
   -h        Output this help and exit
   -v        Output version and exit

XSD (XML Schema Definition)

XSD, a recommendation of the World Wide Web Consortium (W3C), specifies how to formally describe the elements in an Extensible Markup Language (XML) document. It can be used by programmers to verify each piece of item content in a document. They can check if it adheres to the description of the element it is placed in.

XSD can be used to express a set of rules to which an XML document must conform in order to be considered "valid" according to that schema. However, unlike most other schema languages, XSD was also designed with the intent that determination of a document's validity would produce a collection of information adhering to specific data types. Such a post-validation infoset can be useful in the development of XML document processing software.

Contributing

Contributions are welcome! Open a pull request to fix a bug, or open an issue to discuss a new feature or change. XSD is compliant with XML Schema Part 1: Structures Second Edition.

Licenses

This program is under the terms of the BSD 3-Clause License. See https://opensource.org/licenses/BSD-3-Clause.

Logo is designed by xuri. Licensed under the Creative Commons 3.0 Attributions license.

xgen's People

Contributors

alexandre-normand avatar batmanaod avatar brianpursley avatar covv avatar dependabot[bot] avatar peng avatar themaxi avatar tvso avatar xuri avatar yagotome avatar yury-egorenkov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

xgen's Issues

Parsing the svg 1.1 xsd produces no code

Description

Using the official SVG specification, xgen produces a go file with just the package statement and the generated comment, but shows no errors.

Steps to reproduce the issue:

  1. Download the svg XSD file from: https://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd
  2. Use xgen command installed via go install (go get is no longer the correct procedure with newer versions of go
  3. Command: xgen -i xsd/ -o svg -p svg -l Go or xgen -i xsd/svg.xsd -o jim -p svg -l Go (various combinations)
  4. Inspect empty output file

Describe the results you received:

// Code generated by xgen. DO NOT EDIT.

package svg

Describe the results you expected:

Generated types as gleaned from the XSD, or some errors

Output of go version:

go version go1.18 darwin/amd64

xgen version or commit ID:

xgen version: 0.1.0

Environment details (OS, physical, etc.):
OSX Version 12.3

Darwin jimi 21.4.0 Darwin Kernel Version 21.4.0: Mon Feb 21 20:34:37 PST 2022; root:xnu-8020.101.4~2/RELEASE_X86_64 x86_64

xsd:byte should be int8 instead of byte in Go

When parsing the "xsd:byte" tag, it parses byte. Byte is unsigned in go, so it should be int8 (signed instead).

Steps to reproduce the issue:

  1. Have an xsd with a byte tag
  2. try to convert to struct

Describe the results you received:
struct with byte
Describe the results you expected:
struct with int8
Output of go version:
go version go1.18 linux/amd64
xgen version or commit ID:
98e2a90

Multiple "xs:list" in "xs:complexType" Causing Error

Description

I am attempting to generate code based on some XSD files that utilize the "include" and "import" syntax. The problem is that I get the following error:

process error on schema/process/services/service/LibraryConfiguration.xsd: 14:7: expected 'IDENT', found '['

I did some investigating and discovered it happens when there are multiple xs:list types at the same level under an xs:complexType. When I comment out two of the three xs:element sections that contain the xs:list, the code can be successfully generated.

Example files used: process.zip

Steps to reproduce the issue:

  1. Using the files above, I run the following command on the process directory:
    xgen -i schema/process/ -p generatedxml -o output/ -l Go
  2. Get the following error:
    process error on schema/process/services/service/LibraryConfiguration.xsd: 14:7: expected 'IDENT', found '['

Steps to fix the example files:

  1. Comment out lines 17-32 of the "LibraryConfiguration.xsd" file (The second and third xs:element sections).
  2. With the modified files run:
    xgen -i schema/process/ -p generatedxml -o output/ -l Go
  3. Code generates successfully.

Output of go version:

go version go1.16.7 darwin/arm64

xgen version or commit ID:

xgen version: 0.1.0

Environment details (OS, physical, etc.):

  • MacBook Pro (M1 Architecture)
  • macOS 11.4 (20F71)

Output of go env:

GO111MODULE=""
GOARCH="arm64"
GOBIN=""
GOCACHE="/Users/barnesew/Library/Caches/go-build"
GOENV="/Users/barnesew/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="arm64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/barnesew/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/barnesew/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_arm64"
GOVCS=""
GOVERSION="go1.16.7"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/barnesew/Documents/tms/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/y0/0w2cgh_s3ls1jbw51q6zrq4r0000gn/T/go-build3987189383=/tmp/go-build -gno-record-gcc-switches -fno-common"

Non-Go types do not appear to be correct

Looking at the map from XSD types to language-specific types in utils.go, it seems there are a number of problems with the non-Go languages:

  • char is used frequently in C and Rust, for instance with ID. These are mapped to strings in Go, TypeScript, and Java, but char is not long enough to store most data (it is a byte in C and a UTF-32 code point in Rust).
    • Similarly, a collection of strings in other languages are represented with a collection of char in C and Rust, rather than a collection of string-like data.
  • It appears that any is used to store raw bytes in TypeScript. Allocating a separate dynamically-typed value for every byte is wasteful and makes deserialized values difficult to use. I think Uint8Array would be preferable to Array<any> for these types.
  • Standard date/time types are only used in Go, but all five languages have standard-library types for dealing with dates and times.

obix xsd breaks xgen

obix xsd breaks xgen

Steps to reproduce the issue:

  1. Use the obix xsd
<?xml version="1.0" encoding="UTF-8"?>
<!--
     OBIX Version 1.1
     Committee Specification 01
     14 September 2015
     Copyright (c) OASIS Open 2015. All Rights Reserved.
     Source: http://docs.oasis-open.org/obix/obix/v1.1/cs01/schemas/
-->
<xs:schema xmlns="http://docs.oasis-open.org/obix/ns/201506" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://docs.oasis-open.org/obix/ns/201506" elementFormDefault="qualified" id="obix">
	<!-- Simple Types
     ===================== -->
	<xs:simpleType name="status">
		<xs:annotation>
			<xs:documentation>The status Facet is used to annotate an Object about the quality and state of the information.</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string">
			<xs:enumeration value="disabled"/>
			<xs:enumeration value="fault"/>
			<xs:enumeration value="down"/>
			<xs:enumeration value="unackedAlarm"/>
			<xs:enumeration value="alarm"/>
			<xs:enumeration value="unacked"/>
			<xs:enumeration value="overridden"/>
			<xs:enumeration value="ok"/>
			<!-- ordered by priority -->
		</xs:restriction>
	</xs:simpleType>
	<xs:simpleType name="contractList">
		<xs:annotation>
			<xs:documentation> A sequence of Contracts referenced by an OBIX Object describing the Contracts which the Object implements. A Contract is a template, defined as an OBIX Object, that is referenced by other Objects by using the URI to the Contract Definition. Each Contract Elements is a URI. In XSD, it is a string because the collection of URIs follows special serialization rules, i.e., URIs are space separated, and the zero length list is specified as "nil", See the specification for details.</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string"/>
	</xs:simpleType>
	<!-- Complex Types
     ===================== -->
	<xs:complexType name="Obj">
		<xs:annotation>
			<xs:documentation>Obj is the common base Object type, from which the other object types are derived.</xs:documentation>
		</xs:annotation>
		<xs:sequence>
			<xs:element ref="obj" minOccurs="0" maxOccurs="unbounded"/>
			<!-- Note to Reviewers:
				The element below was defined in 1.0 and is now removed.
				See note above for details. We recommend new development use namespaces instead.
			<xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
			-->
		</xs:sequence>
		<xs:attribute ref="display"/>
		<xs:attribute ref="displayName"/>
		<xs:attribute ref="href"/>
		<xs:attribute ref="icon"/>
		<xs:attribute ref="is"/>
		<xs:attribute ref="name"/>
		<xs:attribute ref="null"/>
		<xs:attribute ref="status" default="ok"/>
		<xs:attribute ref="ts"/>
		<xs:attribute ref="writable" default="false"/>
	</xs:complexType>
	<xs:complexType name="AbsTime">
		<xs:annotation>
			<xs:documentation>The abstime type is used to represent an absolute point in time. Its val attribute maps to xs:dateTime, with the exception that it MUST contain the timezone.</xs:documentation>
		</xs:annotation>
		<xs:complexContent>
			<xs:extension base="Obj">
				<xs:attribute name="min" type="xs:dateTime"/>
				<xs:attribute name="max" type="xs:dateTime"/>
				<xs:attribute name="val" type="xs:dateTime"/>
				<xs:attribute ref="tz"/>
			</xs:extension>
			<!-- obix 1.1 -->
		</xs:complexContent>
	</xs:complexType>
	<xs:complexType name="Bool">
		<xs:complexContent>
			<xs:extension base="Obj">
				<xs:attribute ref="range"/>
				<xs:attribute name="val" type="xs:boolean" default="false"/>
			</xs:extension>
		</xs:complexContent>
	</xs:complexType>
	<xs:complexType name="Err">
		<xs:complexContent>
			<xs:extension base="Obj"/>
		</xs:complexContent>
	</xs:complexType>
	<xs:complexType name="Enum">
		<xs:annotation>
			<xs:documentation>The enum type is used to represent a value which must match a finite set of values.</xs:documentation>
		</xs:annotation>
		<xs:complexContent>
			<xs:extension base="Obj">
				<xs:attribute ref="range"/>
				<xs:attribute name="val" type="xs:NMTOKEN"/>
			</xs:extension>
		</xs:complexContent>
	</xs:complexType>
	<xs:complexType name="Feed">
		<xs:annotation>
			<xs:documentation>The feed type is used to define a topic for a Feed of events. Feeds are used with Watches to subscribe to a stream of events such as alarms.</xs:documentation>
		</xs:annotation>
		<xs:complexContent>
			<xs:extension base="Obj">
				<xs:attribute ref="in" default="obix:Nil"/>
				<xs:attribute ref="of" default="obix:obj"/>
			</xs:extension>
		</xs:complexContent>
	</xs:complexType>
	<xs:complexType name="Int">
		<xs:complexContent>
			<xs:extension base="Obj">
				<xs:attribute name="min" type="xs:long"/>
				<xs:attribute name="max" type="xs:long"/>
				<xs:attribute ref="unit"/>
				<xs:attribute name="val" type="xs:long" default="0"/>
			</xs:extension>
		</xs:complexContent>
	</xs:complexType>
	<xs:complexType name="List">
		<xs:annotation>
			<xs:documentation>The list type is a specialized Object type for storing a list of other Objects.</xs:documentation>
		</xs:annotation>
		<xs:complexContent>
			<xs:extension base="Obj">
				<xs:attribute name="min" type="xs:long"/>
				<xs:attribute name="max" type="xs:long"/>
				<xs:attribute ref="of" default="obix:obj"/>
			</xs:extension>
		</xs:complexContent>
	</xs:complexType>
	<xs:complexType name="Op">
		<xs:annotation>
			<xs:documentation>The op type is used to define an operation. All operations take one input Object as a parameter, and return one Object as an output. The input and output Contracts are defined via the in and out attributes.</xs:documentation>
		</xs:annotation>
		<xs:complexContent>
			<xs:extension base="Obj">
				<xs:attribute ref="in" default="obix:Nil"/>
				<xs:attribute ref="out" default="obix:Nil"/>
			</xs:extension>
		</xs:complexContent>
	</xs:complexType>
	<xs:complexType name="Real">
		<xs:complexContent>
			<xs:extension base="Obj">
				<xs:attribute name="min" type="xs:double"/>
				<xs:attribute name="max" type="xs:double"/>
				<xs:attribute ref="precision"/>
				<xs:attribute ref="unit"/>
				<xs:attribute name="val" type="xs:double" default="0"/>
			</xs:extension>
		</xs:complexContent>
	</xs:complexType>
	<xs:complexType name="Ref">
		<xs:annotation>
			<xs:documentation>The ref type is used to create an external reference to another OBIX Object.</xs:documentation>
		</xs:annotation>
		<xs:complexContent>
			<xs:extension base="Obj"/>
		</xs:complexContent>
	</xs:complexType>
	<xs:complexType name="RelTime">
		<xs:annotation>
			<xs:documentation>The reltime type is used to represent a relative duration of time.</xs:documentation>
		</xs:annotation>
		<xs:complexContent>
			<xs:extension base="Obj">
				<xs:attribute name="min" type="xs:duration"/>
				<xs:attribute name="max" type="xs:duration"/>
				<xs:attribute name="val" type="xs:duration" default="PT0S"/>
			</xs:extension>
			<!-- obix 1.1 -->
		</xs:complexContent>
	</xs:complexType>
	<xs:complexType name="Str">
		<xs:complexContent>
			<xs:extension base="Obj">
				<xs:attribute name="min" type="xs:long"/>
				<xs:attribute name="max" type="xs:long"/>
				<xs:attribute name="val" type="xs:string" default=""/>
			</xs:extension>
		</xs:complexContent>
	</xs:complexType>
	<xs:complexType name="Uri">
		<xs:complexContent>
			<xs:extension base="Obj">
				<xs:attribute name="val" type="xs:anyURI"/>
			</xs:extension>
		</xs:complexContent>
	</xs:complexType>
	<!-- obix 1.1 -->
	<xs:complexType name="Date">
		<xs:complexContent>
			<xs:extension base="Obj">
				<xs:attribute name="min" type="xs:date"/>
				<xs:attribute name="max" type="xs:date"/>
				<xs:attribute name="val" type="xs:date"/>
			</xs:extension>
		</xs:complexContent>
	</xs:complexType>
	<xs:complexType name="Time">
		<xs:complexContent>
			<xs:extension base="Obj">
				<xs:attribute name="min" type="xs:time"/>
				<xs:attribute name="max" type="xs:time"/>
				<xs:attribute name="val" type="xs:time"/>
			</xs:extension>
		</xs:complexContent>
	</xs:complexType>
	<!-- Global Attributes
     ===================== -->
	<xs:attribute name="display" type="xs:string">
		<xs:annotation>
			<xs:documentation>provides a localized human readable description of the Object</xs:documentation>
		</xs:annotation>
	</xs:attribute>
	<xs:attribute name="displayName" type="xs:string">
		<xs:annotation>
			<xs:documentation>provides a localized human readable name of the Objec</xs:documentation>
		</xs:annotation>
	</xs:attribute>
	<xs:attribute name="href" type="xs:anyURI">
		<xs:annotation>
			<xs:documentation>href of an Obj. If specified, the root Object MUST have an absolute URI. All other hrefs within an obix document are treated as URI references which may be relative.</xs:documentation>
		</xs:annotation>
	</xs:attribute>
	<xs:attribute name="icon" type="xs:anyURI">
		<xs:annotation>
			<xs:documentation>provides a URI reference to a graphical icon which may be used to represent the Object in an user agent</xs:documentation>
		</xs:annotation>
	</xs:attribute>
	<xs:attribute name="in" type="contractList">
		<xs:annotation>
			<xs:documentation>Specifies the input argument type used by this Object.</xs:documentation>
		</xs:annotation>
	</xs:attribute>
	<xs:attribute name="is" type="contractList">
		<xs:annotation>
			<xs:documentation>Names the Contract the Object implements.</xs:documentation>
		</xs:annotation>
	</xs:attribute>
	<xs:attribute name="name" type="xs:NMTOKEN">
		<xs:annotation>
			<xs:documentation/>
		</xs:annotation>
	</xs:attribute>
	<xs:attribute name="null" type="xs:boolean">
		<xs:annotation>
			<xs:documentation>Attribute if True indicates that this Object has no value, has not been configured or initialized, or is otherwise not defined. Null is a boolean</xs:documentation>
		</xs:annotation>
	</xs:attribute>
	<xs:attribute name="of" type="contractList">
		<xs:annotation>
			<xs:documentation>Specifies the type of child Objects contained by this Object.</xs:documentation>
		</xs:annotation>
	</xs:attribute>
	<xs:attribute name="out" type="contractList">
		<xs:annotation>
			<xs:documentation>Specifies the output argument type used by this Object.</xs:documentation>
		</xs:annotation>
	</xs:attribute>
	<xs:attribute name="precision" type="xs:long">
		<xs:annotation>
			<xs:documentation>used to describe the number of decimal places to use for a real value</xs:documentation>
		</xs:annotation>
	</xs:attribute>
	<xs:attribute name="range" type="xs:anyURI">
		<xs:annotation>
			<xs:documentation>used to define the value space of an enumeration. A range attribute is a URI
reference to an obix:Range Object</xs:documentation>
		</xs:annotation>
	</xs:attribute>
	<xs:attribute name="status" type="status">
		<xs:annotation>
			<xs:documentation>used to annotate an Object about the quality and state of the information. Status is a pre-enumerated value as described in the obix Specification.</xs:documentation>
		</xs:annotation>
	</xs:attribute>
	<xs:attribute name="ts" type="xs:string">
		<xs:annotation>
			<xs:documentation>ts or tagspace applies a defined semantic tag to this object. The semantic tags are defined by the tagspaces as referenced in the Lobby</xs:documentation>
		</xs:annotation>
	</xs:attribute>
	<xs:attribute name="tz" type="xs:string">
		<xs:annotation>
			<xs:documentation>used to annotate an abstime, date, or time Object with a timezone. The value of a tz attribute is a zoneinfo string identifier, as specified in the IANA Time Zone (ZoneInfo DB) database.</xs:documentation>
		</xs:annotation>
	</xs:attribute>
	<xs:attribute name="unit" type="xs:anyURI">
		<xs:annotation>
			<xs:documentation>defines a unit of measurement in the SI Units system.</xs:documentation>
		</xs:annotation>
	</xs:attribute>
	<xs:attribute name="writable" type="xs:boolean">
		<xs:annotation>
			<xs:documentation>specifies if this Object can be written by the client. If false (the default), then the Object is read-only.</xs:documentation>
		</xs:annotation>
	</xs:attribute>
	<!-- Global Elements
     ===================== -->
	<xs:element name="obj" type="Obj">
		<xs:annotation>
			<xs:documentation>conveys an obix Object. The Object is the common base type for the derived types. An Object has  associated properties, called Facets, common to all derived types. </xs:documentation>
		</xs:annotation>
	</xs:element>
	<xs:element name="abstime" type="AbsTime" substitutionGroup="obj">
		<xs:annotation>
			<xs:documentation>conveys a representation of an absolute point in time. AbsTime is an xs:dateTime with a mandatory timezone.</xs:documentation>
		</xs:annotation>
	</xs:element>
	<xs:element name="bool" type="Bool" substitutionGroup="obj">
		<xs:annotation>
			<xs:documentation>conveys a boolean value – true or false</xs:documentation>
		</xs:annotation>
	</xs:element>
	<xs:element name="enum" type="Enum" substitutionGroup="obj">
		<xs:annotation>
			<xs:documentation>conveys an enumerated value within a fixed set of choices</xs:documentation>
		</xs:annotation>
	</xs:element>
	<xs:element name="err" type="Obj" substitutionGroup="obj">
		<xs:annotation>
			<xs:documentation>Conveys an Err Object. Its actual semantics are context dependent. Typically err Objects SHOULD include a human readable description of the problem via the display attribute.</xs:documentation>
		</xs:annotation>
	</xs:element>
	<xs:element name="feed" type="Feed" substitutionGroup="obj">
		<xs:annotation>
			<xs:documentation>Conveys a feed of events. Feeds are used with watches to subscribe to a stream of events such as alarms. Feeds are subscribed via Watches</xs:documentation>
		</xs:annotation>
	</xs:element>
	<xs:element name="int" type="Int" substitutionGroup="obj">
		<xs:annotation>
			<xs:documentation>conveys an integer value</xs:documentation>
		</xs:annotation>
	</xs:element>
	<xs:element name="list" type="List" substitutionGroup="obj">
		<xs:annotation>
			<xs:documentation>conveys a list of other Objects.</xs:documentation>
		</xs:annotation>
	</xs:element>
	<xs:element name="op" type="Op" substitutionGroup="obj">
		<xs:annotation>
			<xs:documentation>conveys an operation (Op) type. All operations take one input Object as a parameter, and return one Object as an output. The input and output Contracts are defined via the in and out attributes.</xs:documentation>
		</xs:annotation>
	</xs:element>
	<xs:element name="real" type="Real" substitutionGroup="obj">
		<xs:annotation>
			<xs:documentation>conveys a floating point value</xs:documentation>
		</xs:annotation>
	</xs:element>
	<xs:element name="ref" type="Ref" substitutionGroup="obj">
		<xs:annotation>
			<xs:documentation>conveys an external reference to another obix Object. It is the obix equivalent of the HTML anchor tag.</xs:documentation>
		</xs:annotation>
	</xs:element>
	<xs:element name="reltime" type="RelTime" substitutionGroup="obj">
		<xs:annotation>
			<xs:documentation>stores a relative time value (duration or time span)</xs:documentation>
		</xs:annotation>
	</xs:element>
	<xs:element name="str" type="Str" substitutionGroup="obj">
		<xs:annotation>
			<xs:documentation>conveys a UNICODE string</xs:documentation>
		</xs:annotation>
	</xs:element>
	<xs:element name="uri" type="Uri" substitutionGroup="obj">
		<xs:annotation>
			<xs:documentation>conveys a Universal Resource Identifier</xs:documentation>
		</xs:annotation>
	</xs:element>
	<!-- obix 1.1 -->
	<xs:element name="date" type="Date" substitutionGroup="obj">
		<xs:annotation>
			<xs:documentation>conveys a specific date as day, month, and year</xs:documentation>
		</xs:annotation>
	</xs:element>
	<xs:element name="time" type="Time" substitutionGroup="obj">
		<xs:annotation>
			<xs:documentation>conveys  a time of day in hours, minutes, and seconds. Time values in MUST omit the timezone offset and MUST NOT use the trailing “Z”</xs:documentation>
		</xs:annotation>
	</xs:element>
</xs:schema>
  1. Run xgen
    ~/go/bin/xgen -i obix-v1.1.xsd -o test -l Go
  2. Be puzzled by the generated go code

Describe the results you received:

  • Elements overwrite struct types
  • Elements are defined as a substitution group for obj but are not actually asignable

Describe the results you expected:

  • compileable code

Output of go version:

go1.18.1

xgen version or commit ID:

v0.0.0-20221130013449-4b677f0df988

Go Package Name not Configurable

Just a small one - noticed that the go package name flag (-p something) isn't getting respected, and so it always generates as 'package schema' or whatever the XSD name is.

Great project: XML centric code-generation support for go is a graveyard of broken dreams, and this is the first decent one I've seen.

Unexpected directory creation and wrong filename (extra extension) when using -o to specify a file

Description
When running xgen -l Java -i test/xsd/base64.xsd -o output.java, it unexpectedly creats an empty directory called output.java and a filename called output.java.java that has the generated code.

I'm working on a local change and plan to submit a PR shortly which I think will fix this.

Steps to reproduce the issue:

xgen -l Java -i test/xsd/base64.xsd -o output.java

Describe the results you received:

$ ls -la | grep output.java
drwxr-xr-x  2 bpursley bpursley  4096 Jul 20 09:29 output.java
-rw-rw-r--  1 bpursley bpursley  2066 Jul 20 09:29 output.java.java

Describe the results you expected:

$ ls -la | grep output.java
-rw-rw-r--  1 bpursley bpursley  2066 Jul 20 09:29 output.java

Output of go version:

go version go1.18.1 linux/amd64

xgen version or commit ID:

98e2a901798bddb93c5e532c98afc1f5f139d47e

Environment details (OS, physical, etc.):

$ uname -a
Linux cinlogic-xps13 5.15.0-41-generic #44~20.04.1-Ubuntu SMP Fri Jun 24 13:27:29 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

Update Rust Exporter

Is your feature request related to a problem? Please describe.

The rust exporter currently outputs really old Rust.

Describe the solution you'd like

Update the rust exporter. These are things I noticed

  • No need for extern crate lines
  • No macro_use are necessary anymore
  • Requires use serde::{Serialize, Deserialize}

Describe alternatives you've considered

Currently I'm rewriting the code automatically once generated.

Go language generation for xsd:integer produces wrong code

Description

Generating a binding for an XML Schema containing xsd:integer will result in int. This is an error since xsd:integer is unbounded while the Go type int is a 32-bit signed integer

Steps to reproduce the issue:

  1. Create an XML schema containing an element of type xsd:integer (assuming xmlns:xsd="http://www.w3.org/2001/XMLSchema")
  2. Execute xgen -i myschema.xsd -o myoutput -l Go
  3. Look at the generated myoutput/myschema.xsd.go

Describe the results you received:

type MyType struct {
	Id         int    `xml:"id"`
}

Describe the results you expected:

type MyType struct {
	Id         Int    `xml:"id"`
}

I'm not a Go expert, but I would have expected a type which can represent arbitrary integer values. Maybe big.Int?

Output of go version:

go version go1.15.1 linux/arm

Aurora version or commit ID:

???

Sorry, I don't know aurora

Environment details (OS, physical, etc.):

$ cat /etc/os-release 
NAME="Ubuntu"
VERSION="18.04.5 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.5 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic

Wrong Element genetarion

I'm trying to generate a struct for the bellow element but the result wasn't the expected.
Element

<xs:element name="infNFe" maxOccurs="unbounded">
<!-- Other elements-->
<xs:element name="PIN" minOccurs="0">
	<xs:annotation>
		<xs:documentation>PIN SUFRAMA</xs:documentation>
		<xs:documentation>PIN atribuído pela SUFRAMA para a operação.</xs:documentation>
	</xs:annotation>
	<xs:simpleType>
		<xs:restriction base="xs:string">
			<xs:whiteSpace value="preserve"/>
			<xs:minLength value="2"/>
			<xs:maxLength value="9"/>
			<xs:pattern value="[1-9]{1}[0-9]{1,8}"/>
		</xs:restriction>
	</xs:simpleType>
</xs:element>
</xs:element>

Generated code :

// InfNFe ...
type InfNFe struct {
	XMLName	xml.Name	`xml:"infNFe"`
	Chave	string	`xml:"chave"`
	PIN	*PIN	`xml:"PIN"`
	DPrev	string	`xml:"dPrev"`
	InfUnidCarga	[]*TUnidCarga	`xml:"infUnidCarga"`
	InfUnidTransp	[]*TUnidadeTransp	`xml:"infUnidTransp"`
}

Expected result:

// InfNFe ...
type InfNFe struct {
	XMLName	xml.Name	`xml:"infNFe"`
	Chave	string	`xml:"chave"`
	PIN	*string	`xml:"PIN"`
	DPrev	string	`xml:"dPrev"`
	InfUnidCarga	[]*TUnidCarga	`xml:"infUnidCarga"`
	InfUnidTransp	[]*TUnidadeTransp	`xml:"infUnidTransp"`
}

Output of go version:

go version go1.14.2 windows/amd64

Environment details (OS, physical, etc.):

windows 10 64bits

the generated go file contains a field in a struct that is not in the definition

Description

I'm trying to generate structs for go from the schema provided by Tableau (link below), but I'm getting bad results for this XSD version. For comparison, I'm using c# sourcecode generated with xsd (from mono).

The result structures are different than expected.

Steps to reproduce the issue:

  1. get xsd file from https://help.tableau.com/samples/en-us/rest_api/ts-api_3_17.xsd or use https://gist.github.com/sumia01/f15ee5589f4a020b63bd0e016ebaf5b6#file-ts-api_3_17-xsd
  2. generate output file(s)
xgen -i ts-api_3_17.xsd -o 3.17/schema.go -l Go
  1. compare with reference generated with xsd from Mono (https://www.mono-project.com/docs/getting-started/install). I uploaded it here: https://gist.github.com/sumia01/f551985805e2e84c9a83cee1e9ef59f8

Describe the results you received:
In the generated result, there is a Status string in the SiteType struct.
https://gist.github.com/sumia01/f15ee5589f4a020b63bd0e016ebaf5b6#file-schema-go-L1511

But it shouldn't be there, see the c# reference:
https://gist.github.com/sumia01/f551985805e2e84c9a83cee1e9ef59f8#file-tableau_3_17-cs-L2960

And here is the type definition part from the original xsd, I can't find any reference for status here:
https://gist.github.com/sumia01/f15ee5589f4a020b63bd0e016ebaf5b6#file-ts-api_3_17-xsd-L1797

One more strange behaviour found here. If I comment the following part from xsd (https://gist.github.com/sumia01/f15ee5589f4a020b63bd0e016ebaf5b6#file-ts-api_3_17-xsd-L1418)

            <!-- <xs:element name="status" minOccurs="1" maxOccurs="1">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:enumeration value="Failed" />
                        <xs:enumeration value="Success" />
                    </xs:restriction>
                </xs:simpleType>
            </xs:element> -->

then it's not generated into the SiteType struct. But I don't understand the connection here.

Describe the results you expected:

I'd like to get the same result as in the c# file

Output of go version:

go version go1.19.3 darwin/arm64

xgen version or commit ID:

xgen version: 0.1.0
commit hash: 45dd37dc6afb5afb6ffd28b6e81b760ec6f7e038

Environment details (OS, physical, etc.):

Darwin Sumi-MacBook-Pro.local 22.1.0 Darwin Kernel Version 22.1.0: Sun Oct  9 20:14:30 PDT 2022; root:xnu-8792.41.9~2/RELEASE_ARM64_T8103 arm64

Generated code includes incorrect/invalid copyright & license notice

The generated Go code includes this notice:

// Copyright 2020 The xgen Authors. All rights reserved.
//
// DO NOT EDIT: generated by xgen XSD generator
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

I am not a lawyer, but it seems improbable to me that this is a valid copyright, because "the xgen authors" did not actually write the generated code (generation based on a schema is not a "creative act"). I'm also not sure the license notice is valid; it would surprise me if code generators can automatically apply their own source code's license to the code they generate.

Was this intentional? Can the copyright and license notice be removed from the generated output?

Generate structs in namespaces.

Description

Hello 👋
First of all, thank you for this library!

I'm new to XSD files. I'm having issues using xgen to generate for NORID's EPP .xsd files.

They are available here:
https://teknisk.norid.no/en/registrar/system/dokumentasjon/epp-grensesnitt/

The issue I'm having is that the structs have the same name (being already defined).
I can see there is a targetNamespace and other schema data that probably could fix this?

Or, maybe I'm doing something wrong?

Steps to reproduce the issue:

  1. Run xgen on EPP-XML-Schemas v1.0.2

Describe the results you received:

E.g.

// File: contact-1.0.xsd.go
type CreateType struct {
	XMLName    xml.Name          `xml:"createType"`
	...
	Email      string            `xml:"email"`
	AuthInfo   *AuthInfoType     `xml:"authInfo"`
	Disclose   *DiscloseType     `xml:"disclose"`
}
// File: domain-1.0.xsd.go
type CreateType struct {
	XMLName    xml.Name       `xml:"createType"`
	...
	Registrant string         `xml:"registrant"`
	Contact    []*ContactType `xml:"contact"`
	AuthInfo   *AuthInfoType  `xml:"authInfo"`
}

Describe the results you expected:

Maybe something like this:

// File: contact-1.0.xsd.go
type ContactCreateType struct {
	XMLName    xml.Name          `xml:"createType"`
	...
	Email      string            `xml:"email"`
	AuthInfo   *AuthInfoType     `xml:"authInfo"`
	Disclose   *DiscloseType     `xml:"disclose"`
}
// File: domain-1.0.xsd.go
type DomainCreateType struct {
	XMLName    xml.Name       `xml:"createType"`
	...
	Registrant string         `xml:"registrant"`
	Contact    []*ContactType `xml:"contact"`
	AuthInfo   *AuthInfoType  `xml:"authInfo"`
}

Output of go version:

go version go1.14.5 darwin/amd64

Environment details (OS, physical, etc.):

Mac OSX 10.15.6

Contributing guide does not explain how to run existing tests

Description

It is unclear how to run the existing xgen test suite, and it appears that doing so may require special permissions.

Details:

CONTRIBUTING.md recommends running the existing test suite, but does not give instructions for doing so. Running go test ./... in the root of the xgen repo results in the following error (repeated several times):

                Error:          Received unexpected error:
                                stat data/xsd: no such file or directory

Examining the GitHub Action workflow file, it appears that most of the tests live in a separate repository:

    - name: Checkout test XSD
      uses: actions/checkout@v2
      with:
        repository: xuri/xsd
        token: ${{ secrets.GIT_TOKEN }}
        path: data

...however, it appears the github.com/xuri/xsd repo is private (I get a 404 from that URL).

PS:

I have elided most of the sections from the template because they don't seem relevant, since I am not reporting a bug in xgen behavior per se. I am happy to provide additional info if asked!

For context, I was hoping to investigate #7 because it is blocking my work.

Go: infinite self-referencing type generated for embedded simpleType with base restriction

Description

When element's type is embedded as a child simpleType and has a base restriction then the Go code contains self-referencing type definition that causes infinite loop in xml marshalling.

Steps to reproduce the issue:

  1. For the xsd file like this one:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:complexType name="header">
        <xs:sequence>
            <xs:element name="operation">
                <xs:simpleType>
                    <xs:restriction base="operationCode"/>
                </xs:simpleType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
    <xs:simpleType name="operationCode">
        <xs:restriction base="xs:string">
            <xs:length value="3"/>
        </xs:restriction>
    </xs:simpleType>
</xs:schema>
  1. Run:
xgen -i xsd/op.xsd -p schema -o output -l Go
  1. The following model is generated:
// Code generated by xgen. DO NOT EDIT.

package schema

import (
	"encoding/xml"
)

// Header ...
type Header struct {
	XMLName   xml.Name   `xml:"header"`
	Operation *Operation `xml:"operation"`
}

// Operation ...
type Operation *Operation

// OperationCode ...
type OperationCode string
  1. And this goes into infinite loop:
package main

import (
	"encoding/xml"
	"os"

	schema "github.com/xuri/xgen/data/output"
)

func main() {
	xml.NewEncoder(os.Stdout).Encode(&schema.Header{})
}

Describe the results you received:

// Code generated by xgen. DO NOT EDIT.

package schema

import (
	"encoding/xml"
)

// Header ...
type Header struct {
	XMLName   xml.Name   `xml:"header"`
	Operation *Operation `xml:"operation"`
}

// Operation ...
type Operation *Operation

// OperationCode ...
type OperationCode string

Describe the results you expected:

// Code generated by xgen. DO NOT EDIT.

package schema

import (
	"encoding/xml"
)

// Header ...
type Header struct {
	XMLName   xml.Name       `xml:"header"`
	Operation *OperationCode `xml:"operation"`
}

// OperationCode ...
type OperationCode string

Output of go version:

xgen version: 0.1.0

xgen version or commit ID:

2afb9de (HEAD -> master, origin/master, origin/HEAD) Upgrade GitHub Actions workflow toolchain version

Environment details (OS, physical, etc.):

$ uname -a
Linux thinkpad 5.13.0-39-generic #44~20.04.1-Ubuntu SMP Thu Mar 24 16:43:35 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/marcin/.cache/go-build"
GOENV="/home/marcin/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/marcin/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/marcin/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/marcin/.local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/marcin/.local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.17.3"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/marcin/projects/xgen/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build1566108439=/tmp/go-build -gno-record-gcc-switches"

Types declared at the end of the XSD are not substituted into the generated code

Description
Types declared at the end of the XSD are not substituted into the generated code.

XSD file:
XSD.txt

Generated file:
Gotype.txt

Describe the results you received:

type CField struct {
	Uid            *String36  `xml:"Uid"`
	Name           *String500 `xml:"Name"`
	YStart         int        `xml:"YStart"`
	YEnd           int        `xml:"YEnd"`
	IdCFieldType   int        `xml:"IdCFieldType"`
	IdCFieldStatus int        `xml:"IdCFieldStatus"`
	MaxCount       int        `xml:"MaxCount"`
	NAgree         int        `xml:"NAgree"`
	CDir           int        `xml:"CDir"`
	DateE          string     `xml:"DateE"`
	FormLst        *FormLst   `xml:"FormLst"`
	LevelLst       *LevelLst  `xml:"LevelLst"`
}

Describe the results you expected:

type CField struct {
	Uid            string    `xml:"Uid"`
	Name           string    `xml:"Name"`
	YStart         int       `xml:"YStart"`
	YEnd           int       `xml:"YEnd"`
	IdCFieldType   int       `xml:"IdCFieldType"`
	IdCFieldStatus int       `xml:"IdCFieldStatus"`
	MaxCount       int       `xml:"MaxCount"`
	NAgree         int       `xml:"NAgree"`
	CDir           int       `xml:"CDir"`
	DateE          string    `xml:"DateE"`
	FormLst        *FormLst  `xml:"FormLst"`
	LevelLst       *LevelLst `xml:"LevelLst"`
}

I have made a quick and dirty fix which works for my schemas:
themaxi@2691c98
Generated file:
GotypeFix.txt

But I think a more correct and more thoughtful solution should be implemented.

Output of go version:

go version go1.17.6 linux/amd64

xgen version or commit ID:

github.com/xuri/xgen v0.0.0-20220120053031-4e87e56e80f1

Environment details (OS, physical, etc.):
Ubuntu 20.04

xgen not generating omitempty for minOccurs = 0 & not creating arrays when maxOccurs = 'unbounded'

Description

While generating Go XML objects with xgen, I have been noticing that omitempty is not being added to elements that have minOccurs='0' when those elements should be optional. I have also noticed that when an element contains <xsd:sequence maxOccurs='unbounded'> it is not producing an array of the element inside the sequence to allow for multiples of the element.

Steps to reproduce the issue:

  1. Run xgen on an xsd file similar to this example
<?xml version="1.0" encoding="UTF-8"?>

<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema'>

 <xsd:element name='CoreContainer'>
  <xsd:complexType>
   <xsd:sequence>
    <xsd:element ref='VideoDocument' minOccurs='0' maxOccurs='unbounded'/>
   </xsd:sequence>
   <xsd:anyAttribute processContents="skip"/>
  </xsd:complexType>
 </xsd:element>

 <xsd:simpleType name='not_empty_string'>
  <xsd:restriction base="xsd:string">
   <xsd:pattern value="\s*\S+(.|\n|\r)*"/>
  </xsd:restriction>
 </xsd:simpleType>

 <xsd:element name='VideoDocument'>
  <xsd:complexType>
   <xsd:all>
    <xsd:element ref='metaData' minOccurs='0' />
   </xsd:all>
   <xsd:attribute name='video_id' type='not_empty_string' use='required'/>
  </xsd:complexType>
 </xsd:element>

 <xsd:element name='metaData'>
  <xsd:complexType>
   <xsd:sequence maxOccurs='unbounded'>
    <xsd:element ref='datumItem'/>
   </xsd:sequence>
  </xsd:complexType>
 </xsd:element>

 <xsd:element name='datumItem'>
  <xsd:complexType>
    <xsd:all>
     <xsd:element name='value' type='not_empty_string'/>
     <xsd:element name='label' type='not_empty_string'/>
    </xsd:all>
  </xsd:complexType>
 </xsd:element>

</xsd:schema>
  1. Run xgen -i xsd/example.xsd -p example_xgen -o xgen_output -l Go
  2. Get output file with the following xml objects
// Code generated by xgen. DO NOT EDIT.

package ivi_xgen

import (
	"encoding/xml"
)

// CoreContainer ...
type CoreContainer struct {
	VideoDocument []*VideoDocument `xml:"VideoDocument"`
}

// Notemptystring ...
type Notemptystring string

// VideoDocument ...
type VideoDocument struct {
	VideoidAttr string          `xml:"video_id,attr"`
	MetaData    *MetaData `xml:"metaData"`
}

// MetaData ...
type MetaData struct {
	XMLName   xml.Name   `xml:"metaData"`
	DatumItem *DatumItem `xml:"datumItem"`
}

// DatumItem ...
type DatumItem struct {
	XMLName xml.Name `xml:"datumItem"`
	Value   string   `xml:"value"`
	Label   string   `xml:"label"`
}

Describe the results you received:

The results I received:

// VideoDocument ...
type VideoDocument struct {
	VideoidAttr string          `xml:"video_id,attr"`
	MetaData    *MetaData `xml:"metaData"`
}

// MetaData ...
type MetaData struct {
	XMLName   xml.Name   `xml:"metaData"`
	DatumItem *DatumItem `xml:"datumItem"`
}

MetaData is not omitempty and DatumItem in Metadata, only allows for one DatumItem when I should be able to have multiple.

Describe the results you expected:

// VideoDocument ...
type VideoDocument struct {
	VideoidAttr string          `xml:"video_id,attr"`
	MetaData    *MetaData `xml:"metaData,omitempty"`
}

// MetaData ...
type MetaData struct {
	XMLName   xml.Name    `xml:"metaData"`
	DatumItem []DatumItem `xml:"datumItem"`
}

MetaData is optional and you can have multiple DatumItems in MetaData.

Output of go version:

go version go1.17.7 darwin/amd64

xgen version or commit ID:

v0.0.0-20220303053931-2afb9de4af9b

Environment details (OS, physical, etc.):
OSX version 12.3

Empty type on xsd:element not handled as anyType ?

Description

I am using xgen to generate code in go.

The xsd extract is:

<xsd:complexType name="AccountHolder_Type">
xsd:sequence
xsd:choice
<xsd:element name="Individual" type="dpi:NameReportableSeller_Type"/>
xsd:sequence
<xsd:element name="Organisation" type="dpi:OrganisationParty_Type"/>
<xsd:element name="AcctHolderType"/>
</xsd:sequence>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>

and the code generated for that Type is:

type AccountHolderType struct {
XMLName xml.Name xml:"AccountHolder_Type"
Individual *NameReportableSellerType xml:"Individual"
Organisation *OrganisationPartyType xml:"Organisation"
AcctHolderType *AcctHolderType xml:"AcctHolderType"
}

And that AcctHolderType points to nothing, and, to be honest, not sure if it should generate a type or a string or it is that the XSD needs to declare its type there.

Steps to reproduce the issue:

  1. Use xgen to generate the code in goLang
  2. Use the DPIXML_v1.08.xsd from https://www.oecd.org/tax/exchange-of-tax-information/DPI-DAC7-XML-Schema-and-User-Guide-v2.03.zip

Describe the results you received:
type AccountHolderType struct {
XMLName xml.Name xml:"AccountHolder_Type"
Individual *NameReportableSellerType xml:"Individual"
Organisation *OrganisationPartyType xml:"Organisation"
AcctHolderType *AcctHolderType xml:"AcctHolderType"
}
Describe the results you expected:
Not really sure what to expect, but code does not compile as there is no AcctHolderType type declared
Output of go version:

go version go1.16.15 linux/amd64

xgen version or commit ID:

xgen version: 0.1.0

Environment details (OS, physical, etc.):
Fedora35

xs:union is interpreted wrongly

Description
If XSD contains xs:union in type definition, it produces struct that contains both values. As result, XML fails to be parsed
Steps to reproduce the issue:

  1. Example XSD:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:simpleType name="integer-or-empty">
    <xs:union memberTypes="xs:integer empty-string" />
  </xs:simpleType>
  <xs:simpleType name="empty-string">
    <xs:restriction base="xs:string">
      <xs:enumeration value="" />
    </xs:restriction>
  </xs:simpleType>
  <xs:element name="NETWORK_ACCESS_URL">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="DomainCensus" maxOccurs="1" minOccurs="0">
          <xs:complexType>
            <xs:simpleContent>
              <xs:extension base="xs:string">
                <xs:attribute type="integer-or-empty" name="AccessCount"/>
              </xs:extension>
            </xs:simpleContent>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>
  1. Run following command
xgen -i filename.xsd -o report.go -l Go -p report
  1. Following Go code is generated:
// Code generated by xgen. DO NOT EDIT.

package report

import (
	"encoding/xml"
)

// Integerorempty ...
type Integerorempty struct {
	XMLName     xml.Name `xml:"integer-or-empty"`
	Emptystring *Emptystring
	Integer     int
}

// Emptystring ...
type Emptystring string

// DomainCensus ...
type DomainCensus struct {
	AccessCountAttr *Integerorempty `xml:"AccessCount,attr,omitempty"`
	Value           string          `xml:",chardata"`
}

// NETWORKACCESSURL ...
type NETWORKACCESSURL struct {
	XMLName      xml.Name      `xml:"NETWORK_ACCESS_URL"`
	DomainCensus *DomainCensus `xml:"DomainCensus"`
}
  1. Here is sample XML to parse (report.xml):
<?xml version="1.0" encoding="UTF-8"?>
<NETWORK_ACCESS_URL>
  <DomainCensus AccessCount="149511825">84786</DomainCensus>
</NETWORK_ACCESS_URL>
  1. Test code (file report_test.go):
package report

import (
	"encoding/xml"
	"os"
	"testing"
)

func TestReport(t *testing.T) {
	data, err := os.ReadFile("report.xml")
	if err != nil {
		t.Fatal(err)
	}
	var report NETWORKACCESSURL
	if err := xml.Unmarshal(data, &report); err != nil {
		t.Fatal(err)
	}
}

Describe the results you received:
go test produces the following:

--- FAIL: TestReport (0.00s)
    report_test.go:16: cannot unmarshal into report.Integerorempty
FAIL
exit status 1
FAIL	github.com/mpkondrashin/ddan/report/t	0.251s

Describe the results you expected:
I have expected to parse file successfully
Output of go version:

go version go1.18.3 darwin/amd64

xgen version or commit ID:

xgen version: 0.1.0

Environment details (OS, physical, etc.):
MacOS Monterey

Possible solution
I have no clue, how to solve it as unions of types are not supported by Golang (not sure about other languages).

What worked for me: Changing Integerorempty to int through whole report.go file (using Search & Replace) fixes this issue

I assume some option to force some types to be substituted as other types would be the solution. See #10 issue. This option would solve this issue too (interpret xsd "integer" as int, int64 or big.Int as user whats it to)

How to handle the actual text content of an element?

Is your feature request related to a problem? Please describe.

Looks like the generated types don't have any place for the actual text content of an element

Describe the solution you'd like

A field should be generated for the element text. For example xxxText where xxx is the element name.

Additional context
Here's an example xsd:

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:complexType name="SomeType">
    <xsd:simpleContent>
      <xsd:extension base="xsd:string">
        <xsd:attribute ref="SomeTypeId" use="required" />
      </xsd:extension>
    </xsd:simpleContent>
  </xsd:complexType>
</xsd:schema>

And the generated (TypeScript) types:

// Code generated by xgen. DO NOT EDIT.

// SomeType ...
export class SomeType {
	SomeTypeIdAttr: SomeTypeId;
}

Maybe change to something like:

export class SomeType {
	SomeTypeIdAttr: SomeTypeId;
        SomeTypeText: string
}

The xxxText might be too generic, but something like that

Enums not generated properly in certain circumstances

Description
Sometimes, depending on the schema, enums are not generated correctly, or are not generated at all.

Steps to reproduce the issue:
Schema:

<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:here="http://example.org/" targetNamespace="http://example.org/">

    <element name="TopLevel">
        <complexType>
            <choice minOccurs="1" maxOccurs="unbounded">
                <element name="TShirt" type="here:SizeType" minOccurs="0" />
                <element name="Style" minOccurs="0">
                    <simpleType>
                        <restriction base="string">
                            <enumeration value="Value1" />
                            <enumeration value="Value2" />
                        </restriction>
                    </simpleType>
                </element>
            </choice>
        </complexType>
    </element>

    <simpleType name="SizeType">
        <restriction base="string">
            <enumeration value="Small" />
            <enumeration value="Medium" />
            <enumeration value="Large" />
        </restriction>
    </simpleType>

    <simpleType name="HasNoElements">
        <restriction base="string">
        </restriction>
    </simpleType>

</schema>

Command:

xgen -l TypeScript -i example.xsd

Describe the results you received:

// Code generated by xgen. DO NOT EDIT.

// TopLevel ...
export class TopLevel {
	TShirt: Array<SizeType>;
	Style: string;
}

// Style ...
export type Style = string;

// HasNoElements ...
export enum HasNoElements {
	Value1 = 'Value1',
	Value2 = 'Value2',
	Small = 'Small',
	Medium = 'Medium',
	Large = 'Large',
}

Describe the results you expected:

// Code generated by xgen. DO NOT EDIT.

// TopLevel ...
export class TopLevel {
	TShirt: Array<SizeType>;
	Style: string;
}

// Style ...
export type Style = string;

// SizeType ...
export enum SizeType {
	Small = 'Small',
	Medium = 'Medium',
	Large = 'Large',
}

// HasNoElements ...
export type HasNoElements = string;

Output of go version:

go version go1.18.1 linux/amd64

xgen version or commit ID:

98e2a901798bddb93c5e532c98afc1f5f139d47e

Environment details (OS, physical, etc.):

$ uname -a
Linux cinlogic-xps13 5.15.0-41-generic #44~20.04.1-Ubuntu SMP Fri Jun 24 13:27:29 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

Other Information:
If I omit the HasNoElements enum from the schema, the generated code also omits the SizeType enum for some reason:

<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:here="http://example.org/" targetNamespace="http://example.org/">

    <element name="TopLevel">
        <complexType>
            <choice minOccurs="1" maxOccurs="unbounded">
                <element name="TShirt" type="here:SizeType" minOccurs="0" />
                <element name="Style" minOccurs="0">
                    <simpleType>
                        <restriction base="string">
                            <enumeration value="Value1" />
                            <enumeration value="Value2" />
                        </restriction>
                    </simpleType>
                </element>
            </choice>
        </complexType>
    </element>

    <simpleType name="SizeType">
        <restriction base="string">
            <enumeration value="Small" />
            <enumeration value="Medium" />
            <enumeration value="Large" />
        </restriction>
    </simpleType>

</schema>
// Code generated by xgen. DO NOT EDIT.

// TopLevel ...
export class TopLevel {
	TShirt: Array<SizeType>;
	Style: string;
}

// Style ...
export type Style = string;

Also...

If I omit the Style element from the top level element, then it works fine:

<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:here="http://example.org/" targetNamespace="http://example.org/">

    <element name="TopLevel">
        <complexType>
            <choice minOccurs="1" maxOccurs="unbounded">
                <element name="TShirt" type="here:SizeType" minOccurs="0" />
            </choice>
        </complexType>
    </element>

    <simpleType name="SizeType">
        <restriction base="string">
            <enumeration value="Small" />
            <enumeration value="Medium" />
            <enumeration value="Large" />
        </restriction>
    </simpleType>

</schema>

Output:

// Code generated by xgen. DO NOT EDIT.

// TopLevel ...
export class TopLevel {
	TShirt: string;
}

// SizeType ...
export enum SizeType {
	Small = 'Small',
	Medium = 'Medium',
	Large = 'Large',
}

So there is some interaction involving the top level element I think. Also, I think the order of the elements in the schema seems to have some effect too. There seem to be a lot of factors involved in reproducing this.

TypeScript sequence `element`s are always `Array`s

It appears that elements in a sequence are always treated as arrays by the TypeScript code generator. For instance, the existing base64.xsd test translates this XSD type:

  <complexType name="myType4">
    <sequence>
      <element name="title" type="string"/>
      <element name="blob" type="base64Binary"/>
      <element name="timestamp" type="dateTime"/>
    </sequence>
  </complexType>

...into this TypeScript type:

export class MyType4 {
	Title: Array<string>;
	Blob: Array<Array<any>>;
	Timestamp: Array<string>;
}

I believe the correct type would be:

export class MyType4 {
	Title: string;
	Blob: Array<any>;
	Timestamp: string;        // see issue #14
}

Array is generated althought minOccurs = 1 and maxOccurs = 1

Description

When the xsd file has an element with minOccurs="1" and maxOccurs="1", an array of elements if generated although in this case just a single element would be appropriate.

Steps to reproduce the issue:

  1. Use for example the following xsd file
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="SomeXmlFile">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="SomeElement" type="string" minOccurs="1" maxOccurs="1"  />
        <xsd:element name="SomeOtherElement"  type="string" minOccurs="1" maxOccurs="1" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>
  1. Run xgen -i test.xsd -o test -l Go

Describe the results you received:
The generated Go file contains:

 // Code generated by xgen. DO NOT EDIT.
package schema

// SomeXmlFile ...
type SomeXmlFile struct {
  SomeElement      []string `xml:"SomeElement"`
  SomeOtherElement []string `xml:"SomeOtherElement"`
}

Describe the results you expected:

 // Code generated by xgen. DO NOT EDIT.
package schema

// SomeXmlFile ...
type SomeXmlFile struct {
  SomeElement      string `xml:"SomeElement"`
  SomeOtherElement string `xml:"SomeOtherElement"`
}

Child element omitted if attribute with enumeration is passed

Description

I've tried to boil it down to the simplest example. I have an XSD as follows:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
  <xs:element name="template">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="requests"/>
        <xs:element minOccurs="0" ref="responses"/>
      </xs:sequence>
      <xs:attribute name="type" use="required">
        <xs:simpleType>
          <xs:restriction base="xs:string">
            <xs:enumeration value="avp"/>
            <xs:enumeration value="condition"/>
            <xs:enumeration value="routing"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
  </xs:element>
  <xs:element name="requests" />
  <xs:element name="responses" />
</xs:schema>

After generating, the following is generated:

// Code generated by xgen. DO NOT EDIT.

package schema

import (
	"encoding/xml"
)

// Template ...
type Template struct {
	XMLName  xml.Name    `xml:"template"`
	TypeAttr interface{} `xml:"type,attr"`
	Requests *Requests   `xml:"requests"`
	Template string      `xml:"template"`
}

// Requests ...
type Requests *Requests

// Responses ...
type Responses *Responses

This is missing the Responses key in the Template struct, but adds a Template string property from.. somewhere.

Removing the <xs:simpleType> segment:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
  <xs:element name="template">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="requests" />
        <xs:element minOccurs="0" ref="responses" />
      </xs:sequence>
      <xs:attribute name="type" use="required" />
    </xs:complexType>
  </xs:element>
  <xs:element name="requests" />
  <xs:element name="responses" />
</xs:schema>

results in a struct that looks more correct:

// Template ...
type Template struct {
	XMLName   xml.Name    `xml:"template"`
	TypeAttr  interface{} `xml:"type,attr"`
	Requests  *Requests   `xml:"requests"`
	Responses *Responses  `xml:"responses"`
}

// Requests ...
type Requests *Requests

// Responses ...
type Responses *Responses

Output of go version:

go version go1.16.2 darwin/amd64

xgen version or commit ID:

v0.0.0-20210301142127-04f2cd700cdb

Environment details (OS, physical, etc.):
MacOS, physical

Created Go type but it was not used.

Description
Xgen is creating a Go type for a element but the type was not used.

The xsd used is this one:
e400101_v1.00.xsd.zip

Steps

$ go get -u github.com/xuri/xgen
go: github.com/xuri/xgen upgrade => v0.0.0-20200517172312-9d8630233132
go: finding module for package golang.org/x/net/html/charset
go: found golang.org/x/net/html/charset in golang.org/x/net v0.0.0-20200513185701-a91f0712d120
go: golang.org/x/text upgrade => v0.3.2
$ xgen -l Go -p evento -o ./v1.00/evento/ -i ./schemas/Evento_AlertaFisco_v1.01/e400101_v1.00.xsd
done

Describe the results you received:

type DetEvento struct {
	XMLName     xml.Name    `xml:"detEvento"`
	VersaoAttr  interface{} `xml:"versao,attr,omitempty"`
	DescEvento  *DescEvento `xml:"descEvento"`
	COrgaoAutor *TCodUfIBGE `xml:"cOrgaoAutor"`
	TpAutor     *TpAutor    `xml:"tpAutor"`
	VerAplic    *TVerAplic  `xml:"verAplic"`
	XObs        *XObs       `xml:"xObs"`
	MotivoCanc  *MotivoCanc `xml:"motivoCanc"`
	CPFOper     *TCpf       `xml:"CPFOper"`
	NomeOper    *NomeOper   `xml:"nomeOper"`
	RepOper     string      `xml:"repOper"`
}

// RepOper ...
type RepOper string

Describe the results you expected:

type DetEvento struct {
	XMLName     xml.Name    `xml:"detEvento"`
	VersaoAttr  interface{} `xml:"versao,attr,omitempty"`
	DescEvento  *DescEvento `xml:"descEvento"`
	COrgaoAutor *TCodUfIBGE `xml:"cOrgaoAutor"`
	TpAutor     *TpAutor    `xml:"tpAutor"`
	VerAplic    *TVerAplic  `xml:"verAplic"`
	XObs        *XObs       `xml:"xObs"`
	MotivoCanc  *MotivoCanc `xml:"motivoCanc"`
	CPFOper     *TCpf       `xml:"CPFOper"`
	NomeOper    *NomeOper   `xml:"nomeOper"`
	RepOper     RepOper      `xml:"repOper"`
}

// RepOper ...
type RepOper string

or

type DetEvento struct {
	XMLName     xml.Name    `xml:"detEvento"`
	VersaoAttr  interface{} `xml:"versao,attr,omitempty"`
	DescEvento  *DescEvento `xml:"descEvento"`
	COrgaoAutor *TCodUfIBGE `xml:"cOrgaoAutor"`
	TpAutor     *TpAutor    `xml:"tpAutor"`
	VerAplic    *TVerAplic  `xml:"verAplic"`
	XObs        *XObs       `xml:"xObs"`
	MotivoCanc  *MotivoCanc `xml:"motivoCanc"`
	CPFOper     *TCpf       `xml:"CPFOper"`
	NomeOper    *NomeOper   `xml:"nomeOper"`
	RepOper     string      `xml:"repOper"`
}

Output of go version:

go version go1.14.2 windows/amd64

opt.Element stack can get corrupted, leading to false output

Description
I stumbled upon this bug because some simple types were missing from my output. The opt.Element stack sometimes contains elements which have already been processed by the parser. This leads to at least two problems when a simple type is being processed after this happened at least once. Assume there is a stand alone simple type with some restrictions, let's say maxLength. In xmlMaxLength.go line 17, the EndMaxLength handler falsely thinks that the simple type being processed is part of an element, pops the simple type off the stack and overwrites the type of the element on the stack. The first problem caused by this is that the simple type will not appear in the output file any more. It is simply omitted. The second problem is that the type of the element may be overwritten with a wrong type.

Steps to reproduce the issue:

  1. As an example, use this Swiss eGov xsd file: http://www.ech.ch/xmlns/eCH-0058/5/eCH-0058-5-0.xsd
  2. Run it through xgen and notice that among several others, the simple type actionType (line 59 in xsd) is missing from the output. (I used xgen to output a Go file, but the language shouldn't matter.)
  3. You may insert log statements in the parser logging the opt.Element stack to see what it looks like. You will notice that both elements "metaDataName" and "metaDataValue" remain in the stack after they have been processed by the parser.

Root of the problem:
Let's focus on where an element get's removed from the stack first. In my case, the elements did not contain any additional complex types, so we can ignore xmlComplexType.go. There is only one other place where elements are removed from the stack, namely in xmlElement.go line 74. This line is never reached if the element is part of a complex type. (The if condition one line earlier will fail because opt.ComplexType.Len() is greater than zero.) In line 51, elements are added to the stack if they have no "type" attribute. My conclusion is that any element which is part of a complex type, does not contain complex types itself and has no "type" attribute is added but never removed from the stack. This corrupts the state of the opt.Element stack and causes the described problems.

Proposed solution:
I am no expert in xsd, so I cannot say what a perfect handling of the opt.Element stack would look like. I certainly asked myself why not every element is added and removed from the stack. I was able to fix the bug for my own case, but I believe what I did could potentially lead to other bugs. I added an else-if condition to the EndElement handler which removes an element from the stack if there are exactly one element and one complex type on their respective stacks:

func (opt *Options) EndElement(ele xml.EndElement, protoTree []interface{}) (err error) {
	if opt.Element.Len() > 0 && opt.ComplexType.Len() == 0 {
		opt.ProtoTree = append(opt.ProtoTree, opt.Element.Pop())
	} else if opt.Element.Len() == 1 && opt.ComplexType.Len() == 1 {
		opt.Element.Pop()
	}
	return
}

Here's where I believe this could cause other problems: Assume that in part of an xsd file there is an element in a complex type in an element, something like this:

<xs:element name="first">
	<xs:complexType>
		<xs:element name="second">
		</xs:element>
	</xs:complexType>
</xs:element>

Also assume the first element is added to the stack, while the second is not. When the end of the second element is being parsed, the else-if condition I added will be true and the first element is removed from the stack, even though it is not done being processed yet.

Since I was able to fix the bug for my specific case and I'm no expert on xsd files, it doesn't make sense for me to work on a general solution. That is all the information I gathered, I hope it is useful.

xs:choise looses some of the chooses.

Description
Under certain conditions, some of the choices in an xs:choice do not get generated. In the enclosed example, there is on a6 field in the generated go code. This bug is subtle!!! If you remove the input for the "d" attribute from the source file, it will generate all 6 of the a elements.

Steps to reproduce the issue:

  1. Run xgen with the go output option on the test case.
  2. save the output
  3. Remove the code for the d attribute from the test case and rerun.
    here is the input to use
    =============

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="e">
xs:complexType
<xs:choice maxOccurs="unbounded">
<xs:element ref="a1"/>
<xs:element ref="a2"/>
<xs:element ref="a3"/>
<xs:element ref="a4"/>
<xs:element ref="a5"/>
<xs:element ref="a6"/>
</xs:choice>
<xs:attribute name="d" use="required">
xs:simpleType
<xs:restriction base="xs:token">
<xs:enumeration value="2"/>
<xs:enumeration value="3"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="a1">
xs:complexType
<xs:attribute name="n" use="required" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="a2">
xs:complexType
<xs:attribute name="n" use="required" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="a3">
xs:complexType
<xs:attribute name="n" use="required" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="a4">
xs:complexType
<xs:attribute name="n" use="required" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="a5">
xs:complexType
<xs:attribute name="n" use="required" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="a6">
xs:complexType
<xs:attribute name="n" use="required" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:schema>

=============
Describe the results you received:
// Code generated by xgen. DO NOT EDIT.

package test1

import (
"encoding/xml"
)

// E ...
type E struct {
XMLName xml.Name xml:"e"
DAttr string xml:"d,attr"
A1 []*A1 xml:"a1"
A2 []*A2 xml:"a2"
A3 []*A3 xml:"a3"
A4 []*A4 xml:"a4"
A5 []*A5 xml:"a5"
E string xml:"e"
}

// A1 ...
type A1 struct {
XMLName xml.Name xml:"a1"
NAttr string xml:"n,attr"
}

// A2 ...
type A2 struct {
XMLName xml.Name xml:"a2"
NAttr string xml:"n,attr"
}

// A3 ...
type A3 struct {
XMLName xml.Name xml:"a3"
NAttr string xml:"n,attr"
}

// A4 ...
type A4 struct {
XMLName xml.Name xml:"a4"
NAttr string xml:"n,attr"
}

// A5 ...
type A5 struct {
XMLName xml.Name xml:"a5"
NAttr string xml:"n,attr"
}

// A6 ...
type A6 struct {
XMLName xml.Name xml:"a6"
NAttr string xml:"n,attr"
}

Describe the results you expected:
// Code generated by xgen. DO NOT EDIT.

package test1

import (
"encoding/xml"
)

// E ...
type E struct {
XMLName xml.Name xml:"e"
DAttr string xml:"d,attr"
A1 []*A1 xml:"a1"
A2 []*A2 xml:"a2"
A3 []*A3 xml:"a3"
A4 []*A4 xml:"a4"
A5 []*A5 xml:"a5"
A6 []*A6 xml:"a6"
E string xml:"e"
}

// A1 ...
type A1 struct {
XMLName xml.Name xml:"a1"
NAttr string xml:"n,attr"
}

// A2 ...
type A2 struct {
XMLName xml.Name xml:"a2"
NAttr string xml:"n,attr"
}

// A3 ...
type A3 struct {
XMLName xml.Name xml:"a3"
NAttr string xml:"n,attr"
}

// A4 ...
type A4 struct {
XMLName xml.Name xml:"a4"
NAttr string xml:"n,attr"
}

// A5 ...
type A5 struct {
XMLName xml.Name xml:"a5"
NAttr string xml:"n,attr"
}

// A6 ...
type A6 struct {
XMLName xml.Name xml:"a6"
NAttr string xml:"n,attr"
}

Output of go version:
xgen version: 0.1.0

(paste your output here)

xgen version or commit ID:

(paste here)

Environment details (OS, physical, etc.):
ubuntu 20.04 x86-64

Illegal characters in enum element names for TypeScript.

Description

Note: I'm only interested in TypeScript, so I didn't test any other languages.

When generating code for TS and there's an enum type (enumeration) it could have illegal characters, such as ".". Those should be replaced by underscore. It doesn't matter because the type uses the exact string as the value of each constant. So the name doesn't really matter as long as it's always generated the same way.
Here's an example of how it would be done using JAX:

@XmlType(name = "exampleEnumType")
@XmlEnum
public enum ExampleEnumType{
    @XmlEnumValue("FOO.BAR")
    FOO_BAR("FOO.BAR"),
    ...

Steps to reproduce the issue:

  1. Use XSD that has enumeration with characters that are illegal in TS (i.e. EcmaScript)
  2. xgen -l TypeScript -i ".\foo.xsd" -o "foo"
  3. Compile the generated code.

You can use this as an example: https://share.ech.ch/xmlns/eCH-0196/2/eCH-0196-2-0.xsd
The enum SecurityTypeType is the problem.

Describe the results you received:

Constant names with ".".

Describe the results you expected:

Constant names with "_" instead of ".".

Output of go version:

go version go1.16.5 windows/amd64

xgen version or commit ID:

xgen version: 0.1.0

Environment details (OS, physical, etc.):

Doesn't matter.

How to install??

What does mean go get -u -v github.com/xuri/xgen/cmd/... installation command in README?

go: go.mod file not found in current directory or any parent directory.
        'go get' is no longer supported outside a module.
        To build and install a command, use 'go install' with a version,
        like 'go install example.com/cmd@latest'
        For more information, see https://golang.org/doc/go-get-install-deprecation
        or run 'go help get' or 'go help install'.

go install github.com/xuri/xgen@latest :

go: downloading github.com/xuri/xgen v0.0.0-20230225022412-aec4e71118ac
package github.com/xuri/xgen is not a main package

Can support `extension`?

image
such as this, the CurrentTerritoryCode is base in namespace avs:CurrentTerritoryCode, but the CurrentTerritoryCode in avs is:
image
the gen go code is:
image
is it incorrect?

Support for generating code from the NeTEx XSD schema

Is your feature request related to a problem? Please describe.

When creating code from the NeTEx XSD, I end up with a single Go file which does not encompass the entire distribution.

./go/bin/xgen -i /home/skinkie/Sources/NeTEx/xsd/NeTEx_publication.xsd -o /tmp/go-netex -l Go

Source: https://github.com/NeTEx-CEN/NeTEx/

Describe the solution you'd like

I would like to retrieve a data model for the entire distribution.

Describe alternatives you've considered

This is my first attempt to see if Go is capable of handling XSDs. For other languages I am using JAXB (Java) and xsData (Python).

Generated code does not generate field for simple value

Description

I have a (simplified) XSD as follows (partial but functional example):

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="attribute">
        <xs:complexType>
            <xs:simpleContent>
                <xs:extension base="xs:string">
                    <xs:attribute type="xs:string" name="origin" use="required"/>
                </xs:extension>
            </xs:simpleContent>
        </xs:complexType>
    </xs:element>
</xs:schema>

The XML that goes with it would look like this:

<?xml version="1.0" encoding="utf-8"?>
<attribute origin="reqavp">Destination-Host</attribute>

(I confirmed my XSD is valid and would produce the desired XML structure by copying it into http://xsd2xml.com/)

But the Go struct generated by xgen looks as follows:

// Copyright 2020 The xgen Authors. All rights reserved.
//
// DO NOT EDIT: generated by xgen XSD generator
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package schema

import (
	"encoding/xml"
)

// Attribute ...
type Attribute struct {
	XMLName    xml.Name `xml:"attribute"`
	OriginAttr string   `xml:"origin,attr"`
}

There is no field where I can put the 'value' (Destination-Host) of the attribute tag.

Is my XSD invalid, can I edit it to have the expected 'value' field, or is this an issue in the generator? I'm expecting a struct like:

type Attribute struct {
	XMLName    xml.Name `xml:"attribute"`
	OriginAttr string   `xml:"origin,attr"`
	Value      string   `xml:",chardata"`
}

Is there also a way to mark a struct field as xml:",cdata" ? Or will this involve editing the generated code?

Go Generator - Main type generates incorrect xml: tag

Description

The xml tag for the top type is generated incorrectly, which makes i impossible to unmarshall in to the top structure.

Steps to reproduce the issue:

  1. Start with the svg xsd definition and generate a struct for it
  2. Try to unmarshal an svg string in to an instance
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="500pt" height="300pt" viewBox="0 0 500 300" version="1.1">
    <defs>
        <clipPath id="clip1">
            <path d="M 51 203 L 135 203 L 135 269.839844 L 51 269.839844 Z M 51 203 "/>
        </clipPath>
        <clipPath id="clip2">
            <path d="M 167 190 L 251 190 L 251 269.839844 L 167 269.839844 Z M 167 190 "/>
        </clipPath>
        <clipPath id="clip3">
            <path d="M 282 177 L 366 177 L 366 269.839844 L 282 269.839844 Z M 282 177 "/>
        </clipPath>
        <clipPath id="clip4">
            <path d="M 397 32 L 481 32 L 481 269.839844 L 397 269.839844 Z M 397 32 "/>
        </clipPath>
    </defs>
    <g id="surface1521">
...
  1. You will receive an error: expected element type <svgType> but have <svg>

Describe the results you received:

Unable to parse an svg XML file because the generated tag for xml appends Type to the XML tag:

// SvgType ...
type SvgType struct {
	XMLName                       xml.Name `xml:"svgType"`

It does this for all XMLName declarations. Then will declare:

type Svg *SvgType

Which also will then sometimes generate duplicates because it does not distinguish between things like simpletype and complextype. For instance with SVG you will see:

type Title string
type Title *TitleType

Describe the results you expected:

An unmarshalled svg struct, with the generated tag being xml:"svg"

Output of go version:

go version go1.18 darwin/amd64

xgen version or commit ID:

xgen version: 0.1.0

Environment details (OS, physical, etc.):
OSX version 12.3

xsd:group generates incorrect output in Go

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

Errors in generated Go code: <modelName> redeclared in this block

Description

Generated Go code contains errors

Steps to reproduce the issue:

  1. Download https://developer.tomtom.com/assets/downloads/intermediate-traffic-service/DATEXIISchema_1_0_1_0_HDT_HDF__TomTomVersion9.xsd
  2. xgen -i DATEXIISchema_1_0_1_0_HDT_HDF__TomTomVersion9.xsd -o .\output -l Go

Describe the results you received:
Several errors due to redeclaration of certain identifiers, e.g.:
MeasurementSpecificCharacteristics redeclared in this block
MeasuredValue redeclared in this block (see details)

Describe the results you expected:
Naming conficts should be avoided if the XSD is valid. In go, you could create separate packages to isolate the models or generate model names differently.

Output of go version:

go version go1.17 windows/amd64

xgen version or commit ID:

 github.com/xuri/xgen v0.0.0-20220303053931-2afb9de4af9b

Environment details (OS, physical, etc.):
Windows 10 x64

Rust: "xs:string" being results in a "char" type.

Thanks for the library, I am looking at using it for Go project and its pretty useful.

Was comparing it with the Rust output, I noticed that a "xs:string" is turned into a char type since String is not in the Rust BuildinTypes pick list. I'd suggest for the time being that String is added here instead, while there may be other option more suited to different performance needs, String would be a good general use case start and not incorrect like char is.

However, this would need some additional logic on your end to map the types since https://github.com/xuri/xgen/blob/master/genRust.go#L152 is just doing a simple bool check.

Support for xsd:choice plurality

Is your feature request related to a problem? Please describe.

I've got an XSD using xsd:choice which isn't currently supported by xgen. Choices don't provide much as far as something that needs to be represented in generated code except for the plurality since a choice can be something like:

<complexType name="TopLevel">
  <choice minOccurs="0" maxOccurs="unbounded">
      <element name="myType1" type="here:myType1" />
      <element name="myType2" type="here:myType2" />
  </choice>
</complexType>

In the example case above, the generated code should be plural versions of myType1 and myType2 because the choice container says that maxOccurs is unbounded.

Describe the solution you'd like
xgen should see choice elements and propagate the choice's plurality to the elements it contains. Since xgen doesn't generate anything regarding validation of min/max occurrences, this should be all there is to it to support xsd:choice elements.

Generated code for the example above (Go) would be something like:

type TopLevel struct {
	MyType1         []*MyType1   `xml:"myType1"`
	MyType2         []*MyType2   `xml:"myType2"`
}

Additional context
I've got a PR almost ready for this one.

Redeclaration in output go code

Description

This seems related to #8, but I dont need an enhancement in the xgen tool, just a way to solve the problem below.

I am having a similar problem when trying to use xgen on the Grobid xsd files: xgen -i ./grobid/grobid-home/schemas/xsd -o ./pkg/extraction/grobid -p grobid -l Go

It creates all the corresponding go files, albeit in a weird directory path (pkg/extraction/grobid/grobid/grobid-home/schemas/xsd/), but after moving the files to the expected path, the go compiler complains found packages schema (Grobid.xsd.go) and grobid (dcr.xsd.go). If I manually change the package from schema to grobid in Grobid.xsd.go I get a bunch of errors related to redeclared in this block. Is there any way to work around this issue?

Steps to reproduce the issue:

  1. xgen -i ./grobid/grobid-home/schemas/xsd -o ./pkg/extraction/grobid -p grobid -l Go
  2. mv pkg/extraction/grobid/grobid/grobid-home/schemas/xsd/* pkg/extraction/grobid && rm -rf pkg/extraction/grobid/grobid/grobid-home
  3. Build:
pkg/extraction/extraction.go:25:2: found packages schema (Grobid.xsd.go) and grobid (dcr.xsd.go) in /Users/ojg/code/corpora/server/pkg/extraction/grobid```
5. Change package name to `grobid` in `Grobid.xsd.go` and build:
```go build -o bin/test .
pkg/extraction/grobid/tei.xsd.go:10:6: P redeclared in this block
	pkg/extraction/grobid/Grobid.xsd.go:2606:6: other declaration of P
pkg/extraction/grobid/tei.xsd.go:20:6: Hi redeclared in this block
	pkg/extraction/grobid/Grobid.xsd.go:2616:6: other declaration of Hi

Describe the results you received:

The code did not compile compile - see output above.

Describe the results you expected:

The code to compile.

Output of go version:

go version go1.22.1 darwin/arm64

xgen version or commit ID:

xgen version: 0.1.0

Environment details (OS, physical, etc.):

macOS 14.4 on MacBook Pro with M2.

Does Nothing?

Description

The program produces no output and exits zero saying "done". I wanted to debug this, but I had some issue with package name resolution.

Steps to reproduce the issue:

cat <<- "EOF" > schema.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
    targetNamespace="bks" xmlns="bks">
    <xs:element name="books">
        <xs:complexType>
            <xs:sequence maxOccurs="unbounded" minOccurs="0">
                <xs:element name="book" type="ctbook"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:complexType name="ctbook">
        <xs:sequence>
            <xs:element name="title" type="xs:string"/>
            <xs:element name="author" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>
EOF
go get -u -v github.com/xuri/xgen/cmd/...
xgen -v
# xgen version: 0.1.0
xgen -i schema.xsd -o ./output -l Go
# done
ls -al output
# empty

Describe the results you received:

The output directory is empty.

Describe the results you expected:

Expected the program to produce some output.

Output of go version:

go version go1.14.1 darwin/amd64

Generating Go code from BPMN schemas

Hello! I'm trying to generate Go code based on the BPMN schemas (they can be found in the previous link - BPMN20.xsd being the main one).

Here is the generated Go code for the BPMN20.xsd schema:

// Copyright 2020 The xgen Authors. All rights reserved.
//
// DO NOT EDIT: generated by xgen XSD generator
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package schema

import (
	"encoding/xml"
)

// Definitions ...
type Definitions *TDefinitions

// TDefinitions ...
type TDefinitions struct {
	XMLName                xml.Name         `xml:"tDefinitions"`
	IdAttr                 string           `xml:"id,attr,omitempty"`
	NameAttr               string           `xml:"name,attr,omitempty"`
	TargetNamespaceAttr    string           `xml:"targetNamespace,attr"`
	ExpressionLanguageAttr string           `xml:"expressionLanguage,attr,omitempty"`
	TypeLanguageAttr       string           `xml:"typeLanguage,attr,omitempty"`
	ExporterAttr           string           `xml:"exporter,attr,omitempty"`
	ExporterVersionAttr    string           `xml:"exporterVersion,attr,omitempty"`
	Import                 []*TImport       `xml:"import"`
	Extension              []*TExtension    `xml:"extension"`
	RootElement            []*TRootElement  `xml:"rootElement"`
	BpmndiBPMNDiagram      []*BPMNDiagram   `xml:"bpmndi:BPMNDiagram"`
	Relationship           []*TRelationship `xml:"relationship"`
}

// Import ...
type Import *TImport

// TImport ...
type TImport struct {
	XMLName        xml.Name `xml:"tImport"`
	NamespaceAttr  string   `xml:"namespace,attr"`
	LocationAttr   string   `xml:"location,attr"`
	ImportTypeAttr string   `xml:"importType,attr"`
}

Also, here is an example BPMN file:

<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI">
   <bpmn:process id="Process">
      <bpmn:startEvent id="foo" name="foo">
         <bpmn:extensionElements>
            <foo/>
         </bpmn:extensionElements>
         <bpmn:outgoing>Foo</bpmn:outgoing>
         <bpmn:messageEventDefinition id="foo" messageRef="foo" />
      </bpmn:startEvent>
      <bpmn:task id="foo4" name="foo">
         <bpmn:extensionElements>
            <foo/>
         </bpmn:extensionElements>
         <bpmn:incoming>foo</bpmn:incoming>
      </bpmn:task>
      <bpmn:sequenceFlow id="foo" sourceRef="foo" targetRef="foo" />
   </bpmn:process>
   <bpmn:message id="foo" name="foo" />
   <bpmndi:BPMNDiagram>
      <bpmndi:BPMNPlane bpmnElement="Process">
         <bpmndi:BPMNShape bpmnElement="foo">
            <dc:Bounds x="32.84375" y="47.5" width="36" height="36" />
         </bpmndi:BPMNShape>
         <bpmndi:BPMNShape bpmnElement="foo">
            <dc:Bounds x="214.84375" y="100.5" width="100" height="80" />
         </bpmndi:BPMNShape>
         <bpmndi:BPMNEdge bpmnElement="foo">
            <di:waypoint x="50.84375" y="65.5" />
            <di:waypoint x="264.84375" y="140.5" />
         </bpmndi:BPMNEdge>
      </bpmndi:BPMNPlane>
   </bpmndi:BPMNDiagram>
</bpmn:definitions>

The issue I have is that I can't figure out how to unmarshal definitions elements (they appear in the generated code as type Definitions *TDefinitions). Shouldn't they be documented with `xml:"definitions"` in order for the XML parser to be able to parse them? I'm new to go so it's very possible that I'm missing something here.

Thank you in advance!

Go: `gDay` cannot be parsed as `time.Time`

Description

The XSD gDay type is not a timestamp but a recurring calendar day. Valid values given as examples in RELAX NG by Eric van der Vlist are:

---01, ---01Z, ---01+02:00, ---01-04:00, ---15, and ---31

To reproduce the issue:

Generate schema for xsd file with gDay type (such as test/xsd/base64.xsd)

Describe the results you received:

The Go type used in the generated schema to deserialize gDay elements is time.Time

Describe the results you expected:

The Go type used can be deserialized from a valid gDay string, such as the examples above

configurable TypeScript generators for specific xml parsers

Is your feature request related to a problem? Please describe.

Typescript generation come in very handy when zou try to deal with XML parsing within a typescript project. XML
Parsing is typically handled by a library, which then transforms the XML in a particular JSON-like form or gives accessor
functions to the data.
unfortunatelly xgen generated types cannot be used out of the box for most of the commonly used parsers, without modifying
the source of the xsd to typescript converter.

Describe the solution you'd like

Either separate flavours of the typescript parser could be provided or some configurability would be great in order to get type-definitions
for the JS-result of common XML-parser.

Additional context
For my use case, which was providing type-definitions for the gnucash XSD I was able to slightly modify the source code of the Typescript converter to get a fully typed view of a gnucash-xml, parsed by the fast-xml-parser . The result of the experiment can be seen here: https://github.com/bastiion/gnucash-xml-typescript-experiment/tree/gnucash/src/gnucash/typescript3
The modified branch of xgen can be found here https://github.com/bastiion/xgen/tree/faster-xml-parser-ts

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.