Coder Social home page Coder Social logo

go-xml's People

Contributors

andreynering avatar bombsimon avatar carolinasolfernandez avatar davidalpert avatar doroginin avatar droyo avatar elbuki avatar flisky avatar ianlopshire avatar kohenkatz avatar kortschak avatar kvisscher avatar leth avatar marcuscobden-nbs avatar nrlakin avatar paulbellamy avatar shmsr 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

go-xml's Issues

SOAP multirefs

Let's talk about the elephant in the room: references in SOAP documents. We can generate the greatest type declarations ever, but that won't do us any good in the face of documents such as this:

<Body>
  <multiRef id="obj0" soapenc:root="0" xsi:type="myNS:Part">
    <sku>SJ-47</sku>
  </multiRef>

  <response>
    <arg href="#obj0"/>
  </response>
</Body>

ugh. What's worse, one of the explicit reasons listed in the SOAP spec for references is to support data models that include loops. A loop would cause some problems if we simply tried to flatten a document.

A long time ago I wrote a tiny package that took the "flattening" approach: aqwari.net/exp/soap. That's one approach.

  • Should I bundle flattening code with the generated code for wsdlgen? Seems a little heavy.
  • Make a package to handle the references? I like that today, code generated by xsdgen and wsdlgen has no dependencies outside of the stdlib.

What I am leaning towards is developing a standalone package that users can choose to add to their generated packages if they know they're going to be dealing with references. Something that wraps an xml.Decoder and decodes a document as if it were flattened (while still handling loops in a sane way if possible). That package should have more stringent release engineering/compatibility guarantees, since it will be imported in users' code. But I haven't started this package, so I'm keeping an issue here so I don't forget.

xsdgen: missing dependent type from another namespace

Using xsdgen to generate code from http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd

Produces code such as the following:

type EventStreamType struct {
	Actuate     ActuateType `xml:"actuate,attr"`
	SchemeIdUri string      `xml:"schemeIdUri,attr"`
	Value       string      `xml:"value,attr"`
	Timescale   uint        `xml:"timescale,attr"`
	Items       []string    `xml:",any"`
	Event       []EventType `xml:"urn:mpeg:dash:schema:mpd:2011 Event"`
}

Without including the declaration for ActuateType. Here's the relevant part of the XSD:

<xs:complexType name="EventStreamType">
  <xs:sequence>
    <xs:element name="Event" type="EventType" minOccurs="0" maxOccurs="unbounded"/>
    <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>      
  </xs:sequence>
  <xs:attribute ref="xlink:href"/>
  <xs:attribute ref="xlink:actuate" default="onRequest"/>
  <xs:attribute name="schemeIdUri" type="xs:anyURI" use="required"/>
  <xs:attribute name="value" type="xs:string"/>
  <xs:attribute name="timescale" type="xs:unsignedInt"/>
</xs:complexType>

Notably, the actuate attribute is actually pulled in as a reference to another XSD. The xsdgen package should have known that its type declaration was necessary and produced it in the generated code.

fail to build base64Binary type

The generated definition:

type base64Binary []byte

func (b base64Binary) UnmarshalText(text []byte) (err error) {
	*b, err = base64.StdEncoding.DecodeString(string(text))
	return err
}
func (b base64Binary) MarshalText() ([]byte, error) {
	var buf bytes.Buffer
	enc := base64.NewEncoder(base64.StdEncoding, &buf)
	enc.Write([]byte(b))
	enc.Close()
	return buf.Bytes()
}

There are 3 problems:

  1. *b, err = base64.StdEncoding.DecodeString(string(text)) failed as invalid indirect of b (type base64Binary)

  2. MarshalText failed as not enough arguments to return

  3. The corresponding fields actually are not in base64Binary type.

xsdgen issue - root element

From the xsd specification http://www.fdsn.org/xml/station/fdsn-station-1.0.xsd, the "Root element" defined:

<!--  Root element  -->
<xs:element name="FDSNStationXML" type="fsx:RootType"/>
<!--  Type definitions  -->
<xs:complexType name="RootType">
<xs:annotation>
...

Which means the root element struct name should be "FDSNStationXML", e.g.:

type FDSNStationXML struct {
	SchemaVersion float64       `xml:"schemaVersion,attr"`
...

However, currently xsdgen's output is:

type RootType struct {
	SchemaVersion float64       `xml:"schemaVersion,attr"`
...

This problem only happens in the root element.

xsdgen: type flattening routines are slow and incorrect

The xsdgen package flattens the XSD type hierarchy to produce nicer code.

a → b→ c → anyType

becomes

a → anyType
b → anyType
c → anyType

Practically speaking, instead of generating code like this:

type MyString string
type AllCapitalString MyString
type ShortAllCapitalString AllCapitalString

It generates code like this:

type MyString string
type AllCapitalString string
type ShortAllCapitalString string

This is done in the Config.flatten method. There are so many problems with this function, I don't know where to start.

  • It's slow -- it repeatedly recurses into the type hierarchy, even if all types have similar ancestry.
  • It's expensive -- it builds up a big slice of xsd.Type items that usually contains lots of duplicates
  • It's complicated -- not only does it flatten types, it opportunistically elides types that it deems useless, filters types not in the whitelist, unpacks struct types when it can, and who knows what else.
  • It's wrong -- see in #14 where it does not correctly collect all types needed for a given subset of types.

The cfg.flatten and cfg.flatten1 functions need a redo, with the following goals:

  • Do one transformation at a time, rather than all at once.
  • Use memoization to skip flattening type hierarchies we've seen before.
  • If necessary, extend and use the internal/dependency package's Graph type to model dependencies between derived types and the types of their attributes, elements and ancestors, to avoid missing indirectly required types.

gentests: _testgen/gentest.go uses internal import from aqwari.net/xml

When I attempt to follow the instructions in the README.md I get the following.

~/src/github.com/droyo/go-xml/gentests [master]$ go generate
_testgen/testgen.go:14:2: use of internal package aqwari.net/xml/internal/gen not allowed
gentest.go:5: running "go": exit status 1
~/src/github.com/droyo/go-xml/gentests [master]$ git rev-parse HEAD
d48ea63e5a613b3e7b7360e2d0f3476ea77c263d

From following the godoc, it appears that this is because this package is in fact aqwari.net/xml, though this isn't noted in the README here, and there is no import comment restricting incorrect imports.

xsdgen on tableau api 3.6 xsd fails to generate

When trying to generate the schema structures for the Tableau 3.6. api, the generation is invalid.

Full xsd is available here: https://help.tableau.com/samples/en-us/rest_api/ts-api_3_6.xsd

More specifically the Lastday in this monthDay attribute is generated as 'type string', while it should have been 'type LastDay string'

    <xs:complexType name="intervalType">
        <xs:attribute name="minutes">
            <xs:simpleType>
                <xs:restriction base="xs:nonNegativeInteger">
                    <xs:enumeration value="15" />
                    <xs:enumeration value="30" />
                </xs:restriction>
            </xs:simpleType>
        </xs:attribute>
        <xs:attribute name="hours">
            <xs:simpleType>
                <xs:restriction base="xs:nonNegativeInteger">
                    <xs:enumeration value="1" />
                    <xs:enumeration value="2" />
                    <xs:enumeration value="4" />
                    <xs:enumeration value="6" />
                    <xs:enumeration value="8" />
                    <xs:enumeration value="12" />
                </xs:restriction>
            </xs:simpleType>
        </xs:attribute>
        <xs:attribute name="weekDay" >
            <xs:simpleType>
                <xs:restriction base="xs:string">
                    <xs:enumeration value="Monday" />
                    <xs:enumeration value="Tuesday" />
                    <xs:enumeration value="Wednesday" />
                    <xs:enumeration value="Thursday" />
                    <xs:enumeration value="Friday" />
                    <xs:enumeration value="Saturday" />
                    <xs:enumeration value="Sunday" />
                </xs:restriction>
            </xs:simpleType>
        </xs:attribute>
        <xs:attribute name="monthDay" >
            <xs:simpleType>
                <xs:union>
                    <xs:simpleType>
                        <xs:restriction base="xs:integer">
                            <xs:minInclusive value="1" />
                            <xs:maxInclusive value="31" />
                        </xs:restriction>
                    </xs:simpleType>
                    <xs:simpleType>
                        <xs:restriction base="xs:string">
                            <xs:enumeration value="LastDay" />
                        </xs:restriction>
                    </xs:simpleType>
                </xs:union>
            </xs:simpleType>
        </xs:attribute>
    </xs:complexType>

I suspect a problem with the union combining 2 different datatypes 'xs:integer' and 'xs:string', but I have not investigated in detail. Other union combining 'xs:integer' with 'xs:integer' works fine.

Currently using this workaround, as there seems to be only 1 xsdSimpleType with a blanc name:

func main() {
	var cfg xsdgen.Config

	cfg.Option(
		xsdgen.IgnoreAttributes("href", "offset"),
		xsdgen.Replace(`[._ \s-]`, ""),
		xsdgen.PackageName("ws"),
		xsdgen.HandleSOAPArrayType(),
		xsdgen.SOAPArrayAsSlice(),
		xsdgen.UseFieldNames(),

		xsdgen.ProcessTypes(func(s xsd.Schema, t xsd.Type) xsd.Type {
			switch t.(type) {
			case *xsd.SimpleType:
				// workaround for the invalid generation of LastDay type,
				st := t.(*xsd.SimpleType)
				if st.Name.Local == "" {
					st.Name.Local = "LastDay"
				}
			}
			return t
		}),
	)
	if err := cfg.GenCLI(os.Args[1:]...); err != nil {
		log.Fatal(err)
	}
}

Elements without a type

Right at the bottom of http://schemas.xmlsoap.org/soap/encoding/ is the line

<xs:element name="anyType"/>

What should we do with that? What does that even mean? What is the correct type of this element? The xsd package will currently give the error

could not find type "" in namespace "" for element "anyType"

Obviously, this is in a W3C-authored XSD, so it must be valid(right?). We'll need to be able to handle such types. From the name, it sounds like a type that can contain anything. One approach would be making xs:anyType the default type for all elements.

Referenced node has no explicit xmlns namespace when marshalling

Hi, I am trying to include the external xmldsig schema into my schema and to generate the structs. This steps works and this is great!
In the next step I use xmlsec1 to sign the marshalled XML but then it complains that it can't find the Signature node.

Error: failed to find default node with name="Signature"

It seems that xmlsec1 expects that the marshalled XML contains a Signaute node with its explicit xmlns namespace/

<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">

When I am marshalling the XML I get a Signature node without its namespace but all its child nodes contain it. Is it somehow possible to achieve that the Signature node also has its namespace explicitly when marshalled?

Result:

<MetaDataType>
  <Signature>
    <SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
      <CanonicalizationMethod xmlns="http://www.w3.org/2000/09/xmldsig#" Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
      <SignatureMethod xmlns="http://www.w3.org/2000/09/xmldsig#" Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
      <Reference xmlns="http://www.w3.org/2000/09/xmldsig#">
        <DigestMethod xmlns="http://www.w3.org/2000/09/xmldsig#" Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
        <DigestValue xmlns="http://www.w3.org/2000/09/xmldsig#"/>
      </Reference>
    </SignedInfo>
    <SignatureValue xmlns="http://www.w3.org/2000/09/xmldsig#"/>
  </Signature>
</MetaDataType>

Schema:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
           elementFormDefault="qualified">
    <xs:import namespace="http://www.w3.org/2000/09/xmldsig#"
               schemaLocation="xmldsig-core-schema.xsd" />

    <xs:element name="MetaData" type="MetaDataType" />
    <xs:complexType name="MetaDataType">
        <xs:sequence>
            <xs:element ref="ds:Signature"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

Generated code:

type MetaDataType struct {
	Signature *SignatureType `xml:" Signature"`
}

type SignatureType struct {
	SignedInfo     *SignedInfoType     `xml:"http://www.w3.org/2000/09/xmldsig# SignedInfo"`
	SignatureValue *SignatureValueType `xml:"http://www.w3.org/2000/09/xmldsig# SignatureValue"`
	KeyInfo        *KeyInfoType        `xml:"http://www.w3.org/2000/09/xmldsig# KeyInfo,omitempty"`
	Object         []ObjectType        `xml:"http://www.w3.org/2000/09/xmldsig# Object,omitempty"`
	Id             string              `xml:"Id,attr,omitempty"`
}

xsdgen problem

Hi,

I've used xsdgen command line to generate xsd from http://www.fdsn.org/xml/station/1 .
However, the generated go skipped the base type for xs:restriction.

For example, if you look into the generated go struct of "Longitude"->"LongitudeType"->"LongitudeBaseType" you'll see there's no "FloatType" field:

type LatitudeBaseType struct {
	Unit       string  `xml:"unit,attr"`
	PlusError  float64 `xml:"plusError,attr"`
	MinusError float64 `xml:"minusError,attr"`
}

, but the xsd of LongitudeBaseType is:

<xs:complexType name="LongitudeBaseType">
		<xs:simpleContent>
			<xs:restriction base="fsx:FloatType">
				<xs:minInclusive value="-180"/>
				<xs:maxInclusive value="180"/>
				<xs:attribute name="unit" type="xs:string" use="optional" fixed="DEGREES"/>
				<xs:attributeGroup ref="fsx:uncertaintyDouble"/>
			</xs:restriction>
		</xs:simpleContent>
	</xs:complexType>

Fixed attribute used improperly

I've misread the XML schema spec. "fixed" has nothing to do with overriding the value of an attribute, and everything to do with preventing derivations of a type from changing the value.

Since the "fixed" attribute is only useful for schema authoring tools and validation tools, it should be dropped completely from the xsd package.

Test generated Go code in `xsdgen`, `wsdlgen` packages

When developing new features and fixing bugs, progress is impeded by the lack of thorough automated tests. There are tests for each package that verify xsd files can be parsed without errors, and that Go code can be generated without errors. However, there is not enough tests of the generated code itself.

Develop unit tests that generate Go code for XSD fragments and check the following:

  • Generated code is valid Go code
  • Sample data is successfully decoded into the generated Go types
  • Go type is encoded to equivalent XML

The tests should be data-driven, so it is easy to add additional test cases just by providing an XSD and some sample data. In the future the tests can be extended to ensure default values are set (see #2), but that is not a requirement for this issue.

Potential challenges

  • The naive way of doing this requires compiling and running a Go program. This will make the tests more complicated and slower at best, flaky and non-portable at worst. Is there any way around compiling a Go program?
  • Encoded XML data will be slightly different from the source XML due to the encoding/xml's handling of XML namespaces, so a simple equivalency == check won't be enough.

xsdgen: issues with wildcards & embedded fields

The dash branch contains the DASH-MPD XSD and sample data in the gentest directory.

Currently the tests fail due to an invalid marshalling of the SegmentList element. It is supposed to generate something like this:

	<SegmentList timescale="90000" duration="5400000">
	  <RepresentationIndex sourceURL="representation-index.sidx">
	  </RepresentationIndex>
	  <SegmentURL media="segment-1.ts">
	  </SegmentURL>
	  ...
	</SegmentList>

Instead we get this:

	<SegmentList timescale="90000" xmlns="urn:mpeg:dash:schema:mpd:2011">
	  <Items>
	  </Items>
	  <Items>
	  </Items>
	  ...
	</SegmentList>

This is due to the <SegmentURL> items being unmarshalled into the wrong place. Here's the the relevant type declarations:

type SegmentListType struct {
	MultipleSegmentBaseType
	Actuate    ActuateType      `xml:"actuate,attr,omitempty"`
	SegmentURL []SegmentURLType `xml:"urn:mpeg:dash:schema:mpd:2011 SegmentURL,omitempty"`
}

Within MultipleSegmentBaseType is the following:

Items                    []string `xml:",any"`

This feels like a possible bug, or at least, unexpected behavior in the encoding/xml package; it is dropping the SegmentURL items into this wildcard field, even though further down SegmentListType there is a more specific field matching those items. This is probably due to the fact that the wildcard field is in an embedded type.

XML from MarshalIndent includes unwanted whitespaces

Thank you for a great library! It's been really helpful for me to use while traversing XML.

I'm using the library to marshal XML from xmltree.Element. The XML generated will in some cases be read by a human and because of that I'm using xmltree.MarshalIndent. The problem is that the XML generated includes too much leading and trailing whitespaces so when being unmarshalled back to the original type (with standard library) the content includes unwanted newlines.

Example to reproduce

package main

import (
	"encoding/xml"
	"fmt"

	"aqwari.net/xml/xmltree"
)

type Test struct {
	Field1 string `xml:"parent>child1"`
	Field2 int    `xml:"parent>child2"`
	Field3 string `xml:"parent>child3"`
}

func main() {
	t := Test{"test string", 10, "another string"}

	// MarshalIndent with standard library
	std, _ := xml.MarshalIndent(t, "", "  ")

	// Parse the mashalled XML with xml tree and MarshalIndent the parsed tree
	elements, _ := xmltree.Parse(std)
	xt := xmltree.MarshalIndent(elements, "", "  ")

	// Print result from both libraries
	fmt.Println(string(std))
	fmt.Println("-")
	fmt.Println(string(xt))

	// Unmarshal the two generated byte slices with standard library
	t1 := Test{}
	t2 := Test{}

	xml.Unmarshal(std, &t1)
	xml.Unmarshal(xt, &t2)

	// The XML from stdandard library contains no whitespaces
	fmt.Printf(
		"Stdlib:  f1 '%s', f2 '%d', f3: '%s'\n",
		t1.Field1, t1.Field2, t1.Field3,
	)

	// The XML from xmltree library contains too much whitespaces
	fmt.Printf(
		"Xmltree: f1 '%s', f2 '%d', f3: '%s'\n",
		t2.Field1, t2.Field2, t2.Field3,
	)
}

Output

<Test>
  <parent>
    <child1>test string</child1>
    <child2>10</child2>
    <child3>another string</child3>
  </parent>
</Test>
-
<Test>
  <parent>
    <child1>
      test string
    </child1>
    <child2>
      10
    </child2>
    <child3>
      another string
    </child3>
  </parent>
</Test>

Stdlib:  f1 'test string', f2 '10', f3: 'another string'
Xmltree: f1 '
      test string
    ', f2 '10', f3: '
      another string
    '

This change to xmltree/marshal.go seems to fix my issues:

diff --git a/xmltree/marshal.go b/xmltree/marshal.go
index 001b63a..1c12495 100644
--- a/xmltree/marshal.go
+++ b/xmltree/marshal.go
@@ -115,16 +115,8 @@ func (e *encoder) encode(el, parent *Element, visited map[*Element]struct{}) err
 }
 
 func (e *encoder) WriteContent(content []byte, depth int) error {
-	if e.pretty {
-		io.WriteString(e.w, e.prefix)
-		for i := 0; i < depth; i++ {
-			io.WriteString(e.w, e.indent)
-		}
-	}
 	e.w.Write(content)
-	if e.pretty && !bytes.HasSuffix(content, []byte("\n")) {
-		io.WriteString(e.w, "\n")
-	}
+
 	return nil
 }
 
@@ -161,7 +153,9 @@ func (e *encoder) encodeOpenTag(el *Element, scope Scope, depth int) error {
 		return err
 	}
 	if e.pretty {
-		io.WriteString(e.w, "\n")
+		if len(el.Children) > 0 || len(el.Content) == 0 {
+			io.WriteString(e.w, "\n")
+		}
 	}
 	return nil
 }
@@ -169,7 +163,9 @@ func (e *encoder) encodeOpenTag(el *Element, scope Scope, depth int) error {
 func (e *encoder) encodeCloseTag(el *Element, depth int) error {
 	if e.pretty {
 		for i := 0; i < depth; i++ {
-			io.WriteString(e.w, e.indent)
+			if len(el.Children) > 0 {
+				io.WriteString(e.w, e.indent)
+			}
 		}
 	}
 	if err := tagTmpl.ExecuteTemplate(e.w, "end", el); err != nil {

So while running the example again with the above changes this is the output:

<Test>
  <parent>
    <child1>test string</child1>
    <child2>10</child2>
    <child3>another string</child3>
  </parent>
</Test>
-
<Test>
  <parent>
    <child1>test string</child1>
    <child2>10</child2>
    <child3>another string</child3>
  </parent>
</Test>

Stdlib:  f1 'test string', f2 '10', f3: 'another string'
Xmltree: f1 'test string', f2 '10', f3: 'another string'

Am I missing something or do you agree that this is a bug? If you agree, do you want me to create a PR?

Thanks!

xsdgen: omitempty and zero-value structs

We need a workaround for https://golang.org/issues/11939. Empty structs (full of zeroes) for which ,omitempty is present on all field tags should not show up in MarshalXML output, but they do. See https://play.golang.org/p/J-_l2JySA0 for a trivial example of the problem.

Solution 1: pointers for all

One solution would be to use pointers for everything. However, I don't want to do that, because it makes the resulting types more difficult to use, as each field access will require if v.FieldName != nil { ... guards.

Solution 2: Smarter MarshalXML methods

Another solution would be to make MarshalXML methods smarter. Ignoring struct embedding which will be gone when #31 is resolved, we can skip emitting the complexType T if the following conditions are satisfied:

  • All of T's fields use the ,omitempty option
  • All of T's fields are the zero value for the field's type

The second condition is kind of annoying to check. Something like this would cover most cases:

if (v == T{})

but it won't compile if T contains a slice, such as with list types or base64Binary derivatives.

Solution 3: Wait for a fix :)

nil base type causes panic in xsdgen/xsdgen.go Config.flatten1()

When a SimpleType without a base type is processed in flatten1(), the debugf() on line xsdgen/xsdgen.go:280 causes xsdgen to crash - calling XMLName(nil) will trigger the panic() in xsd/xsd.go:293.

Since this is only used for debugging, it's probably a good idea to remove the panic() completely or guard this with a check:

		if builtin == nil {
			cfg.debugf("%T(%s) has no base type, cannot transform", t, xsd.XMLName(t).Local)
		} else {
			cfg.debugf("Transforming %T(%s) into base type %T(%s)", t, xsd.XMLName(t).Local, t.Base, xsd.XMLName(t.Base).Local)
		}

And before returning t.Base (which is nil), there should be something like this:

		if t.Base == nil {
			return t
		}

I don't really understand why there is no base type in my particular test case, but handling this special case may be a good idea anyway?

For reference, this is the XSD I'm trying to process:
http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd
And the type that it hits is a ConditionalUintType.

Panic: xsd: unexpected xsd.Type <nil> <nil> passed to XMLName

I try to generate structs for this xsd with this command xsdgen -o schema.go -pkg types -vv Types.xsd and get panic:

*xsd.SimpleType(ordinalNumberText) -> xsd.Builtin(string)
panic: xsd: unexpected xsd.Type <nil> <nil> passed to XMLName

goroutine 1 [running]:
panic(0x1e03a0, 0xc420554c20)
        /usr/local/Cellar/go/1.7.4_2/libexec/src/runtime/panic.go:500 +0x1a1
aqwari.net/xml/xsd.XMLName(0x0, 0x0, 0xc4200715f0, 0x23, 0xc4203daf80, 0x14)
        ./vendor/src/aqwari.net/xml/xsd/xsd.go:290 +0x240
aqwari.net/xml/xsdgen.(*Config).flatten1(0xc4200dc480, 0x3793c0, 0xc420130480, 0xc4205bd128, 0x1, 0xc420588230)
        ./vendor/src/aqwari.net/xml/xsdgen/xsdgen.go:344 +0x358
aqwari.net/xml/xsdgen.(*Config).flatten1(0xc4200dc480, 0x3793c0, 0xc42013e300, 0xc4205bd128, 0x3, 0x3)
        ./vendor/src/aqwari.net/xml/xsdgen/xsdgen.go:332 +0x200
aqwari.net/xml/xsdgen.(*Config).flatten1(0xc4200dc480, 0x3793c0, 0xc4203bb980, 0xc4205bd128, 0x2, 0x2)
        ./vendor/src/aqwari.net/xml/xsdgen/xsdgen.go:332 +0x200
aqwari.net/xml/xsdgen.(*Config).flatten(0xc4200dc480, 0xc4200d15c0, 0x27, 0xc420554840, 0x1)
        ./vendor/src/aqwari.net/xml/xsdgen/xsdgen.go:236 +0x286
aqwari.net/xml/xsdgen.(*Config).gen(0xc4200dc480, 0xc4203fc7e0, 0x1, 0x1, 0xc420556000, 0x5, 0x8, 0x0, 0x30, 0x34848efe00075a08)
        ./vendor/src/aqwari.net/xml/xsdgen/xsdgen.go:147 +0x6cf
aqwari.net/xml/xsdgen.(*Config).GenCode(0xc4200dc480, 0xc4200d6e80, 0x1, 0x1, 0x1, 0x1, 0x0)
        ./vendor/src/aqwari.net/xml/xsdgen/cli.go:41 +0x49b

xsdfetch utility

Some XML schema, such as http://schema.bolagsverket.se/extern/foretagsinformation/F5_Rakenskapsinformation_2.00.xsd , make heavy use of imports. Add a tool, xsdfetch,
that can be used to retrieve all the schema imported by a target schema.

Example usage:

xsdfetch url
xsdfetch filename

Some notes:

  • Oftentimes the schemaLocation field can be relative. In that case, we should treat it as relative to the targetNamespace of the main schema. If that file is not found, we can then consider it relative to the URL of the main file (if we are fetching via URL).
  • Many <import> statements do not contain a schemaLocation. One heuristic to find the schema file, in that case, is to append .xsd to the schema's name space.
  • Some name spaces are not URLs. In that case, if there is no schemaLocation, there's not much we can do.
  • Should handle <import> and <include>.
  • Should fetch dependent schema, and dependencies of their dependencies, and so on.

All schema should be downloaded to the current directory, using path.Base(targetNS) + ".xsd" as the file name, if unique.

Optional struct fields with struct types throwing errors in xsdgen

I think this was introduced in #93 (I hit it merging #93 into my fork because I wanted optional structs to render as pointers).

Running xsdgen throws the following error:

error generating go structs from xsd: oadr2b/oadr2b_tmp.go:1114:16: expected type, found '&' (and 5 more errors) in package oadr2b

In the debug output that follows, I see the following struct rendered:

type X509DataType struct {
	Item             string                          `xml:",any"`
	X509IssuerSerial *X509IssuerSerialType           `xml:"http://www.w3.org/2000/09/xmldsig# X509IssuerSerial,omitempty"`
	X509SKI          *&{%!s(token.Pos=0) <nil> byte} `xml:"http://www.w3.org/2000/09/xmldsig# X509SKI,omitempty"`
	X509SubjectName  string                          `xml:"http://www.w3.org/2000/09/xmldsig# X509SubjectName,omitempty"`
	X509Certificate  *&{%!s(token.Pos=0) <nil> byte} `xml:"http://www.w3.org/2000/09/xmldsig# X509Certificate,omitempty"`
	X509CRL          *&{%!s(token.Pos=0) <nil> byte} `xml:"http://www.w3.org/2000/09/xmldsig# X509CRL,omitempty"`
}

I'm looking at it because I'd like the feature, but you may want to revert. I'll try to add a minimal schema to xsdgen/testdata that replicates the issue in any case.

Schema with top-level elements

Currently, the xsd package ignores top-level elements; if they contain type definitions, it will parse those types and toss the surrounding element. When the wsdlgen package receives a WSDL definition with a message defined by an element instead of a type, it tries to find a type with the same name, which may not necessarily exist. The workaround can be seen in wsdl/wsdl.go#L110 .

The wsdlgen package should support top-level schema elements. This likely requires an extension to the xsd.Schema type that collects such declarations.

xsdgen: Duplicate field names

xsdgen does not ensure struct fields for complex types are named uniquely, so generated code for a type with an attribute and element of the same name will not compile. Using a simple xsd like this:

<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://example.org/">
  <complexType name="myType2">
    <sequence>
      <element name="title" type="string"/>
      <attribute name="title" type="string"/>
    </sequence>
  </complexType>
</schema>

Generates this:

package ws

type MyType2 struct {
	Title string `xml:"title,attr"`
	Title string `xml:"http://example.org/ title"`
}

Which is not valid code. For the attribute/element case in the example, we can append "Attr" to the field name for the attribute. I can't think of other type declarations that would cause this problem, but it's something to be mindful of if we add more support for unions. The relevant portion of the XSD spec is here, I think.

Marshal from Struct

Hello,
I am creating a server that needs to consume and response with soap XML. I currently have consuming soap xml working correctly with xmltree package but is it possible for support to be added to xmltree to generate XML from a struct? I can't use the internal encoding/xml as it requires two structs to marshal and unmarshal which is unmaintainable for my project.
Thanks in advance.

Handle fixed values in marshal methods

When the xsdgen package encounters a struct field with a "fixed" value, it will leave it out of the Go type, because the value is fixed and should not be changed by the user. However, such types need to have the fixed value set in their MarshalXML function to be valid according to the XML schema. Either include fixed values in the Go source, or generate the necessary marshalling functions. This needs to play nice with the existing marshalling methods, if they exist for a type already.

No Base Set for Empty Complex Types

When a complex type is empty, no base is set. This causes panics and unintended behavior elsewhere in the codebase.

example xml:

<xsd:complexType name="Get_Committee_Defintion_Request_CriteriaType">
    <xsd:annotation>
        <xsd:documentation>Committee Definition Request Criteria</xsd:documentation>
    </xsd:annotation>
</xsd:complexType>

I believe a solution to this issue would be to assign a base of AnyType to empty complex types. @droyo Would you suggest anything else?

Stack Overflow when parsing recursive types

Hi, I am trying to use xsdgen with a large xsd file with several large dependencies.

I get this error after a few seconds.

runtime: goroutine stack exceeds 1000000000-byte limit
fatal error: stack overflow

runtime stack:
runtime.throw(0x7a70d4, 0xe)
/usr/local/go/src/runtime/panic.go:608 +0x72
runtime.newstack()
/usr/local/go/src/runtime/stack.go:1008 +0x729
runtime.morestack()
/usr/local/go/src/runtime/asm_amd64.s:429 +0x8f

goroutine 1 [running]:
aqwari.net/xml/xsd.or.func1(0xc000234200, 0x0)
/home/droker/Development/go/src/aqwari.net/xml/xsd/search.go:20 +0x92 fp=0xc02191a368 sp=0xc02191a360 pc=0x597de2
aqwari.net/xml/xsd.hasChild.func1(0xc0004c7300, 0x597db5)
/home/droker/Development/go/src/aqwari.net/xml/xsd/search.go:33 +0x85 fp=0xc02191a3a0 sp=0xc02191a368 pc=0x597e75
aqwari.net/xml/xmltree.(*Element).SearchFunc.func1(0xc0004c7300)
/home/droker/Development/go/src/aqwari.net/xml/xmltree/xmltree.go:327 +0x45 fp=0xc02191a400 sp=0xc02191a3a0 pc=0x565ad5
aqwari.net/xml/xmltree.(*Element).walk(0xc000234100, 0xc0419190e0, 0xc000234100, 0x0)
/home/droker/Development/go/src/aqwari.net/xml/xmltree/xmltree.go:287 +0x3b fp=0xc02191a420 sp=0xc02191a400 pc=0x56520b
aqwari.net/xml/xmltree.(*Element).SearchFunc.func1(0xc000234100)
/home/droker/Development/go/src/aqwari.net/xml/xmltree/xmltree.go:330 +0xa0 fp=0xc02191a480 sp=0xc02191a420 pc=0x565b30
aqwari.net/xml/xmltree.(*Element).walk(0xc000563800, 0xc0419190e0, 0xc000563800, 0x0)
/home/droker/Development/go/src/aqwari.net/xml/xmltree/xmltree.go:287 +0x3b fp=0xc02191a4a0 sp=0xc02191a480 pc=0x56520b
aqwari.net/xml/xmltree.(*Element).SearchFunc.func1(0xc000563800)..............

There is a huge stack trace.

Any ideas if there is anything I can do?

Thanks

Dean

xmltree - non-utf8 charsets

The xmltree package uses xml.Decoder.InputOffset to capture the content of XML tags when constructing the tree. This does not play well with xml.Decoder.CharsetReader. Compared to any of the iso 8859-* encodings, a utf8 encoding of the same text is almost always longer than the source, and InputOffset's return value is the input offset into the translated utf8 text. So simply using CharsetReader naively will likely cause a run-time panic when we hit a non-ascii character.

Fix xmltree to gracefully handle non-utf8 charsets, or expose some way for the user to handle them.

xsd:sequence is not respected when using layout struct to handle non-builtin types

I have an xsd:sequence that has an xsd:dateTime in the 3rd position.
As you know, xsd:sequence is strictly positional.

The generated MarshalXML code declares a layout struct to handle the conversion from time.Time to *xsdDateTime with a new member with the same same (member shadowing)

Unfortunately the shadowing member is serialized at last position, so the generated XML is not validated against the original XSD file

I hope my explanation is clear enough, I am attaching XSD files I am using to reproduce this issue (Italian electronic invoice formats)

sdi.zip

Processing complex XSDs exhausts available memory

I'm trying to use xsdgen on the SAML 2.0 XSD definitions. Specifically, saml-schema-assertion-2.0.xsd as found at:

https://docs.oasis-open.org/security/saml/v2.0/

I went through and manually downloaded the dependencies and ran:

xsdgen saml-schema-assertion-2.0.xsd xmldsig-core-schema.xsd xenc-schema.xsd

The result is that the process's memory starts ballooning until I had to kill it. On my system that was around 32GB of memory. When I ran it with the -vv flag it appears to be going in circles processing the files over and over. I don't know enough about the tool to say if it's stuck in a loop or some sort of NP-complete hell.

Go version: go version go1.13.6 linux/amd64

Attributes need a namespace

In tracking down a validation error I've just discovered that XML attributes need a to specify namespace! I thought I knew XML pretty well, but this was news to me!

For example, in <Foo xmlns="http://bar/" hello="world" /> the hello attribute does not have a namespace.
If we generated this strucure from a schema we were probably expecting it to use the namespace in which it was defined, so we'd need something like <bar:Foo xmlns:bar="http://bar/" bar:hello="world" />

Annotation UnmarshalXML EOF Error

If an annotation contains tokens other than documentation an unnecessary io.EOF error can be passed.

Example element:

<xsd:element name="Country_ISO_Code" type="xsd:string" maxOccurs="1">
    <xsd:annotation>
        <xsd:documentation>ISO Code identifying the country where the naming rules for this name are defined.</xsd:documentation>
        <xsd:appinfo>
            <wd:Validation>
                <xsd:documentation>A valid instance of Country must exist for the value of Country ISO Code.</xsd:documentation>
                <wd:Validation_Message>No Country with that Country Code Exists.</wd:Validation_Message>
            </wd:Validation>
        </xsd:appinfo>
    </xsd:annotation>
</xsd:element>

xsdgen: "could not find ref ds:Signature in ..."

Hi,

I just tried the generator and it gives me this error. I'm not sure if it's a bug or I'm missing something.

$ xsdgen -pkg=types -o=types/evtAdmPrelim.go xsd/evtAdmPrelim.xsd
could not find ref ds:Signature in <xs:element ref="ds:Signature" xmlns="http://www.esocial.gov.br/schema/evt/evtAdmPrelim/v02_04_00" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xs="http://www.w3.org/2001/XMLSchema"></xs:element>

evtAdmPrelim.xsd.txt

xsdgen issue - xmlns in tags

The tags of go struct generated by xsdgen have unnecessary xmlns. This causes unnecessary xmlns while marshalling into xml.
For example, from http://www.fdsn.org/xml/station/fdsn-station-1.0.xsd, one of the generated go struct is like this:

type BaseFilterType struct {
	ResourceId  string    `xml:"resourceId,attr"`
	Name        string    `xml:"name,attr"`
	Items       []string  `xml:",any"`
	Description string    `xml:"http://www.fdsn.org/xml/station/1 Description"`
...
}

When marshalling, the Description will be this:

<Description xmlns="http://www.fdsn.org/xml/station/1"></Description>

The xmlns in elements should be omitted. And only add xmlns in the tag with "attr" of root element.

complexType gives error: could not find type _anon148 in namespace

I'm using the package to create structs of some large XSD files. However I keep getting some error which I can't resolve. I'm not sure whether this is a bug or if I'm doing something wrong myself.

gen.go looks like this:

package schemas

//go:generate xsdgen -ns http://www.w3.org/2000/09/xmldsig# -pkg schemas -o xmldsig-core-schema.go xmldsig-core-schema.xsd
//go:generate xsdgen -ns http://www.registryagency.bg/schemas/deedv2/Fields -pkg schemas -o FieldsSchema.go FieldsSchema.xsd
//go:generate xsdgen -ns http://www.registryagency.bg/schemas/deedv2 -pkg schemas -o DeedV2.go DeedV2.xsd FieldsSchema.xsd
//go:generate xsdgen -ns http://www.registryagency.bg/schemas/envelopev2 -pkg schemas -o Envelopev2.go FieldsSchema.xsd DeedV2.xsd Envelopev2.xsd

The first two lines go well, it's DeedV2.xsd which creates the error: 2018/01/14 06:27:39 complexType SubDeedType: could not find type "_anon148" in namespace http://www.registryagency.bg/schemas/deedv2 for element UIC

The XSD schemas are quite big, even the, in the error mentioned, SubDeedType is already a couple of hundred lines, so I put the schemas on pastebin instead of pasting them here:

DeedV2.xsd: https://pastebin.com/CSaKzDXn
FieldsSchema.xsd: https://pastebin.com/MuSrR29n
EnvelopeV2.xsd: https://pastebin.com/ipjwzkKN
xmldsig-core-schema.xsd: https://pastebin.com/VG14UTuJ

Any help is highly appreciated.

WSDL Response decoding does not seem to work

I cannot, despite my best efforts, find a way to decode the response body.
The envelope is processed fine, just the contents of the Body is not decoded.

I think we need a test case for the generated code, as #25 calls for

xsdgen: duplicated fields for nested complexType

Such as the following diff:

diff --git a/xsd/testdata/ComplexType.xsd b/xsd/testdata/ComplexType.xsd
index f7f060b..dcf9ce8 100644
--- a/xsd/testdata/ComplexType.xsd
+++ b/xsd/testdata/ComplexType.xsd
@@ -5,12 +5,13 @@
     <element name='ContactTitle' type='string'/>
     <element name='Phone' type='string'/>
     <element name='Fax' minOccurs='0' type='string'/>
-    <element name='FullAddress' type='tns:AddressType'/>
+    <element name='FullAddress' ref='tns:AddressType'/>
   </sequence>
   <attribute name='CustomerID' type='token'/>
 </complexType>

-<complexType name='AddressType'>
+<element name='AddressType'>
+<complexType>
   <sequence>
     <element name='Address' type='string'/>
     <element name='City' type='string'/>
@@ -20,3 +21,4 @@
   </sequence>
   <attribute name='CustomerID' type='token'/>
 </complexType>
+</element>
diff --git a/xsd/xsd_test.go b/xsd/xsd_test.go
index 5307fe3..6c461e5 100644
--- a/xsd/xsd_test.go
+++ b/xsd/xsd_test.go
@@ -151,7 +151,7 @@ func unmarshal(t *testing.T, data []byte) blob {

 func parseFragment(t *testing.T, filename string) Schema {
 	const tmpl = `<schema targetNamespace="tns" ` +
-		`xmlns="http://www.w3.org/2001/XMLSchema">%s</schema>`
+		`xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="tns">%s</schema>`
 	data, err := ioutil.ReadFile(filename)
 	if err != nil {
 		t.Fatal(err)

use of internal package not allowed

When I try to get the wsdlgen package with 'go get github.com/droyo/go-xml/wsdlgen', I get:

../github.com/droyo/go-xml/wsdlgen/cli.go:10:2: use of internal package not allowed
../github.com/droyo/go-xml/wsdlgen/cli.go:11:2: use of internal package not allowed

I understood that referencing internal packages outside the tree is not allowed. Any ideas how I can fix this? Thanks!

Use Import / Included schemas for code Generation

Currently it appears the XSDGEN tool does not reference and included/imported schema files.

There is an 'Import' function in the Parser code, but unclear how to use it.

Is there any documentation on how to Code-Gen an XSD Schema that uses extensive external imports ?
My use case is an open standard domain specific XML Schema, which has an extensive data model and uses about 20 different included files (With nested includes/imports).

I can share the entire schema if required as it is public.

arrays of non-trivial builtins

Consider the element declaration below (note the "maxOccurs" attribute)

<element name="timestamps" type="xsd:dateTime" minOccurs="0" maxOccurs="unbounded">

In Go, the ideal declaration for this type would be []time.Time. For scalar types, we can get away with converting a *time.Time to an *xsdDateTime, a private type that we can attach MarshalXML/UnmarshalXML methods to. This doesn't work with slice types: https://play.golang.org/p/ZAOS7gzcUk .

Currently, xsdgen doesn't work at all for this scenario; it will generate code that tries to convert a *[]time.Time to an *xsdDateTime, which fails to compile.

WSDL with multiple services only returns one.

A WSDL can define multiple related services in a single definition, but wsdlgen will only output the last one to appear in the file.

It might be nice to alter wsdl.Parse to return a slice of Definitions instead of a single one and then have wsdlgen create clients for each service. Or at least a single client with appropriate methods calling the right services for each port.

Generate error types for SOAP faults

WSDL allows for the definition of faults that a given RPC may through. They can be defined in the XML schema like any other type.

If we detect that a type is used as a fault, we should generate an Error() string method so that the type can implement the error interface, and try to unmarshal these faults when making SOAP API calls.

Inner-level complexTypes get shadowed if they share the same name

Hi,

I have an XSD like the following:

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema id="listTest" targetNamespace="http://tempuri.org/listTest.xsd" elementFormDefault="qualified" 
  xmlns="http://tempuri.org/listTest.xsd" 
  xmlns:mstns="http://tempuri.org/listTest.xsd" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="outerList">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="interList1" minOccurs="1" maxOccurs="1">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="innerItem" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
              <xs:element name="innerComplex" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="innerComplexStr1" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
                    <xs:element name="innerComplexStr2" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="interList2" minOccurs="1" maxOccurs="1">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="innerItem" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
              <xs:element name="innerComplex" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="innerComplexInt1" type="xs:int" minOccurs="0" maxOccurs="unbounded" />
                    <xs:element name="innerComplexInt2" type="xs:int" minOccurs="0" maxOccurs="unbounded" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

As you can see, there's two complex elements that don't occur at the root level and both share the name innerComplex. The second shadows the first when I run xsdgen and this is the generated Go file:

package ws

type InnerComplex struct {
	InnerComplexStr1 []string `xml:"http://tempuri.org/listTest.xsd innerComplexStr1,omitempty"`
	InnerComplexStr2 []string `xml:"http://tempuri.org/listTest.xsd innerComplexStr2,omitempty"`
}

type InterList1 struct {
	InnerItem    []string       `xml:"http://tempuri.org/listTest.xsd innerItem,omitempty"`
	InnerComplex []InnerComplex `xml:"http://tempuri.org/listTest.xsd innerComplex,omitempty"`
}

type InterList2 struct {
	InnerItem    []string       `xml:"http://tempuri.org/listTest.xsd innerItem,omitempty"`
	InnerComplex []InnerComplex `xml:"http://tempuri.org/listTest.xsd innerComplex,omitempty"`
}

type OuterList struct {
	InterList1 InterList1 `xml:"http://tempuri.org/listTest.xsd interList1"`
	InterList2 InterList2 `xml:"http://tempuri.org/listTest.xsd interList2"`
}

If I rename the second occurrence of innerComplex to something else

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema id="listTest" targetNamespace="http://tempuri.org/listTest.xsd" elementFormDefault="qualified" 
  xmlns="http://tempuri.org/listTest.xsd" 
  xmlns:mstns="http://tempuri.org/listTest.xsd" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="outerList">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="interList1" minOccurs="1" maxOccurs="1">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="innerItem" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
              <xs:element name="innerComplex" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="innerComplexStr1" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
                    <xs:element name="innerComplexStr2" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="interList2" minOccurs="1" maxOccurs="1">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="innerItem" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
              <xs:element name="innerComplexADifferentName" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="innerComplexInt1" type="xs:int" minOccurs="0" maxOccurs="unbounded" />
                    <xs:element name="innerComplexInt2" type="xs:int" minOccurs="0" maxOccurs="unbounded" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

The generated Go code can parse the XML file represented by the schema correctly.

package ws

type InnerComplex struct {
	InnerComplexStr1 []string `xml:"http://tempuri.org/listTest.xsd innerComplexStr1,omitempty"`
	InnerComplexStr2 []string `xml:"http://tempuri.org/listTest.xsd innerComplexStr2,omitempty"`
}

type InnerComplexADifferentName struct {
	InnerComplexInt1 []int `xml:"http://tempuri.org/listTest.xsd innerComplexInt1,omitempty"`
	InnerComplexInt2 []int `xml:"http://tempuri.org/listTest.xsd innerComplexInt2,omitempty"`
}

type InterList1 struct {
	InnerItem    []string       `xml:"http://tempuri.org/listTest.xsd innerItem,omitempty"`
	InnerComplex []InnerComplex `xml:"http://tempuri.org/listTest.xsd innerComplex,omitempty"`
}

type InterList2 struct {
	InnerItem                  []string                     `xml:"http://tempuri.org/listTest.xsd innerItem,omitempty"`
	InnerComplexADifferentName []InnerComplexADifferentName `xml:"http://tempuri.org/listTest.xsd innerComplexADifferentName,omitempty"`
}

type OuterList struct {
	InterList1 InterList1 `xml:"http://tempuri.org/listTest.xsd interList1"`
	InterList2 InterList2 `xml:"http://tempuri.org/listTest.xsd interList2"`
}

I'm terribly sorry about the very artificial looking examples. I hacked it up looking at one of your test-cases. This is the first time I'm having to parse some bulky legacy XML (270kb schema file) and even what code's been generated so far has been greatly helpful!

Amazon MWS schema gives empty generated go file

I'm trying to generate go code from Amazon MWS xsd schema.
Below are files to reproduce the issue:

$ cat ./generate-amazon-mws-from-xsd
#!/bin/bash
wget -N -P zzz -i ./amazon-mws-xsd-urls -B "https://images-na.ssl-images-
amazon.com/images/G/01/rainier/help/xsd/release_4_1/"
cd xxx
go generate

$ cat ./amazon-mws-xsd-urls
amzn-envelope.xsd
amzn-header.xsd
amzn-base.xsd
Inventory.xsd
Price.xsd
OrderAcknowledgement.xsd
OrderFulfillment.xsd

$ cat ./xxx/xxx.go 
package main

//go:generate xsdgen ../zzz/amzn-base.xsd ../zzz/Price.xsd

Namely, first file is a bash script to download schema files, second file is a list of required files and third is a go file with go generate directive.

First of all, I had to change aqwari.net/xml/xsd/parse.go#parseInt() as following:

func parseInt(s string) int {
	s = strings.TrimSpace(s)
	switch s {
	case "":
		return 0
	case "unbounded":
		return -1
	}
	n, err := strconv.Atoi(s)
	if err != nil {
		//TNL: attempt to parse from float
		f, err := strconv.ParseFloat(s, 64)
		if err != nil {
			stop(err.Error())
		}
		n = int(f)
	}
	return n
}

otherwise it failed to parse <xsd:minInclusive value=".01"/> on restriction on xsd:decimal type.

This is an issue by itself, but I want just to fast generate go structs and edit them manually, so I don't bother with validations for the moment.

After that, go generate finished without error, but created an empty output file with only package directive in it.

I also tried to put schema files into the same dir as go file, path is under $GOPATH/src.

Could you please suggest what am I doing wrong or suggest a quick workaround till it fixed?

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.