droyo / go-xml

utility and code-generation libraries for XML
MIT License
302 stars 114 forks source link

complexType gives error: could not find type _anon148 in namespace #65

Closed arjanvaneersel closed 6 years ago

arjanvaneersel commented 6 years ago

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.

droyo commented 6 years ago

This is certainly a bug. Looking at SubDeedType in DeedV2.xsd, I see this:

<xs:complexType name="SubDeedType">
  <xs:sequence>
    <xs:element ref="f:UIC" minOccurs="0" maxOccurs="unbounded">
      ...

and the element being referenced is element UIC in FieldsSchema.xsd

<xs:element name="UIC" >
  <xs:complexType>
    <xs:sequence>
      <xs:element name="CompanyControl" type="xs:string" minOccurs="1" maxOccurs="1"  />
        ...

The xsd package tries to simplify schema by flattening references, like those in SubDeedType, and by naming anonymous types like the one in the UIC element. The documents are much easier to parse & generate code for when there are no references and all types have a name.

You can see this 'simplification' using the aqwari.net/xml/cmd/xsdparse tool. Here's a bit of what it transforms the SubDeedType into:

<xs:complexType name="SubDeedType">
  <xs:complexContent>
    <xs:restriction base="xs:anyType">
      <xs:sequence>
        <xs:element name="UIC" type="_anon148" minOccurs="0" maxOccurs="unbounded" ...

Can you spot the error? _anon148 is not in DeedV2's namespace, it's in FieldsSchema. It should be

        <xs:element name="UIC" type="f:_anon148" minOccurs="0" maxOccurs="unbounded" ...
droyo commented 6 years ago

After reviewing the code, the bug is in the flattenRef function; when copying a reference to an object in another namespace, it fails to qualify any names contained within.

arjanvaneersel commented 6 years ago

I took a look at the flattenRef function, tried to check where this bug could be, but I couldn't find it. Probably, because even after reading the code, logging things, I still don't get completely what's going on.

droyo commented 6 years ago

I should have time to look at this on the weekend. I believe the error is not handling attributes such as "type", which can contain a QName, here.

droyo commented 6 years ago

I've added a test that reproduces the issue in a much smaller example, in the import-type-from-otherns branch.

droyo commented 6 years ago

Thanks for waiting @arjanvaneersel , I ran the command you provided after merging #66 and it produces output now. Please reopen if the issue isn't fixed for you.