I'm trying to generate some classes from xsd definitions with a xsd:redefine tag on Visual Studio 2019, but it enters an infinite loop on Xsd2Code++ Version 5.0.0.47.
This is a simplification of my example:
File Cabecera.xsd:
<?xml version="1.0" encoding="utf-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:sii="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/ssii/fact/ws/SuministroInformacion.xsd" targetNamespace="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/ssii/fact/ws/SuministroInformacion.xsd" elementFormDefault="qualified">
<simpleType name="VersionSiiType">
<restriction base="string" />
</simpleType>
<simpleType name="ClaveTipoComunicacionType">
<restriction base="string" />
</simpleType>
<simpleType name="TextMax120Type">
<restriction base="string">
<maxLength value="120"/>
</restriction>
</simpleType>
<simpleType name="CIFTypeB">
<annotation>
<documentation xml:lang="es">CIF: Blanco, CIF o Secuencia de 9 dígitos o letras mayúsculas</documentation>
</annotation>
<restriction base="string">
<pattern value="((^[a-z|A-Z]{1}\d{7}[a-z|A-Z]{1}$)|(^\d{8}[a-z|A-Z]{1}$)|(^[a-z|A-Z]{1}\d{8}$)|^$|^ {9}$|^[a-z|A-Z]{2}\d{11}$)"/>
</restriction>
</simpleType>
<simpleType name="NIFType">
<annotation>
<documentation xml:lang="es">NIF: Secuencia de 9 dígitos o letras mayúsculas</documentation>
</annotation>
<restriction base="string">
<length value="9"/>
<pattern value="(([a-z|A-Z]{1}\d{7}[a-z|A-Z]{1})|(\d{8}[a-z|A-Z]{1})|([a-z|A-Z]{1}\d{8}))"/>
</restriction>
</simpleType>
<complexType name="CabeceraSiiVersion">
<annotation>
<documentation xml:lang="es"> Datos de contexto de un suministro </documentation>
</annotation>
<sequence>
<element name="IDVersionSii" type="sii:VersionSiiType"/>
</sequence>
</complexType>
<complexType name="PersonaFisicaJuridicaESType">
<annotation>
<documentation xml:lang="es">Datos de una persona física o jurídica Española con un NIF asociado</documentation>
</annotation>
<sequence>
<element name="NombreRazon" type="sii:TextMax120Type"/>
<element name="NIFRepresentante" type="sii:CIFTypeB" minOccurs="0"/>
<element name="NIF" type="sii:NIFType"/>
</sequence>
</complexType>
<complexType name="CabeceraSiiSinTC">
<annotation>
<documentation xml:lang="es"> Datos de contexto de un suministro sin especificar el tipo de comunicacion </documentation>
</annotation>
<complexContent>
<extension base="sii:CabeceraSiiVersion">
<sequence>
<element name="Titular" type="sii:PersonaFisicaJuridicaESType">
<annotation>
<documentation xml:lang="es"> Titular de los libros de registro que suministra la información </documentation>
</annotation>
</element>
</sequence>
</extension>
</complexContent>
</complexType>
<complexType name="CabeceraSii">
<annotation>
<documentation xml:lang="es"> Datos de contexto de un suministro sin especificar el tipo de comunicacion </documentation>
</annotation>
<complexContent>
<extension base="sii:CabeceraSiiSinTC">
<sequence>
<element name="TipoComunicacion" type="sii:ClaveTipoComunicacionType"/>
</sequence>
</extension>
</complexContent>
</complexType>
</schema>
File SuministroInformacion.xsd
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:sii="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/ssii/fact/ws/SuministroInformacion.xsd" targetNamespace="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/ssii/fact/ws/SuministroInformacion.xsd" elementFormDefault="qualified">
<include schemaLocation="Cabecera.xsd" />
<redefine schemaLocation="Cabecera.xsd">
<simpleType name="VersionSiiType">
<restriction base="sii:VersionSiiType">
<enumeration value="1.0"/>
</restriction>
</simpleType>
<simpleType name="ClaveTipoComunicacionType">
<restriction base="sii:ClaveTipoComunicacionType">
<enumeration value="A0">
<annotation>
<documentation xml:lang="es"> A0 Alta (Se añade al libro un registro una nueva factura)</documentation>
</annotation>
</enumeration>
<enumeration value="A1">
<annotation>
<documentation xml:lang="es"> A1 Modificación (La información que se comunica sustituye a la existente relacionada)</documentation>
</annotation>
</enumeration>
<enumeration value="A4">
<annotation>
<documentation xml:lang="es"> Modificación Factura Régimen de Viajeros</documentation>
</annotation>
</enumeration>
</restriction>
</simpleType>
</redefine>
<!-- Suministro genérico -->
<complexType name="SuministroInformacion">
<annotation>
<documentation xml:lang="es">
Sii - Suministro Inmediato de Información, compuesto por datos
de contexto y una secuencia de 1 o más registros.
</documentation>
</annotation>
<sequence>
<element name="Cabecera" type="sii:CabeceraSii"/>
</sequence>
</complexType>
</schema>
The generation options are as follows:
<?xml version="1.0" encoding="utf-8"?>
<auto-generated>
<NameSpace>Negocio</NameSpace>
<Collection>List</Collection>
<codeType>CSharp</codeType>
<EnableDataBinding>False</EnableDataBinding>
<GenerateCloneMethod>False</GenerateCloneMethod>
<GenerateDataContracts>False</GenerateDataContracts>
<DataMemberNameArg>OnlyIfDifferent</DataMemberNameArg>
<DataMemberOnXmlIgnore>False</DataMemberOnXmlIgnore>
<CodeBaseTag>Net40</CodeBaseTag>
<InitializeFields>All</InitializeFields>
<GenerateUnusedComplexTypes>True</GenerateUnusedComplexTypes>
<GenerateUnusedSimpleTypes>True</GenerateUnusedSimpleTypes>
<GenerateXMLAttributes>True</GenerateXMLAttributes>
<OrderXMLAttrib>False</OrderXMLAttrib>
<EnableLazyLoading>False</EnableLazyLoading>
<VirtualProp>False</VirtualProp>
<PascalCase>False</PascalCase>
<AutomaticProperties>True</AutomaticProperties>
<PropNameSpecified>None</PropNameSpecified>
<PrivateFieldName>StartWithUnderscore</PrivateFieldName>
<PrivateFieldNamePrefix></PrivateFieldNamePrefix>
<EnableRestriction>False</EnableRestriction>
<RestrictionMaxLenght>False</RestrictionMaxLenght>
<RestrictionRegEx>False</RestrictionRegEx>
<RestrictionRange>False</RestrictionRange>
<ValidateProperty>False</ValidateProperty>
<ClassNamePrefix></ClassNamePrefix>
<ClassLevel>Public</ClassLevel>
<PartialClass>True</PartialClass>
<ClassesInSeparateFiles>False</ClassesInSeparateFiles>
<ClassesInSeparateFilesDir></ClassesInSeparateFilesDir>
<TrackingChangesEnable>False</TrackingChangesEnable>
<GenTrackingClasses>False</GenTrackingClasses>
<HidePrivateFieldInIDE>False</HidePrivateFieldInIDE>
<EnableSummaryComment>False</EnableSummaryComment>
<EnableAppInfoSettings>False</EnableAppInfoSettings>
<EnableExternalSchemasCache>False</EnableExternalSchemasCache>
<EnableDebug>False</EnableDebug>
<EnableWarn>False</EnableWarn>
<ExcludeImportedTypes>True</ExcludeImportedTypes>
<ExpandNesteadAttributeGroup>False</ExpandNesteadAttributeGroup>
<CleanupCode>False</CleanupCode>
<EnableXmlSerialization>False</EnableXmlSerialization>
<SerializeMethodName>Serialize</SerializeMethodName>
<DeserializeMethodName>Deserialize</DeserializeMethodName>
<SaveToFileMethodName>SaveToFile</SaveToFileMethodName>
<LoadFromFileMethodName>LoadFromFile</LoadFromFileMethodName>
<EnableEncoding>False</EnableEncoding>
<EnableXMLIndent>False</EnableXMLIndent>
<IndentChar>Indent2Space</IndentChar>
<NewLineAttr>False</NewLineAttr>
<OmitXML>False</OmitXML>
<Encoder>UTF8</Encoder>
<Serializer>XmlSerializer</Serializer>
<sspNullable>False</sspNullable>
<sspString>False</sspString>
<sspCollection>False</sspCollection>
<sspComplexType>False</sspComplexType>
<sspSimpleType>False</sspSimpleType>
<sspEnumType>False</sspEnumType>
<XmlSerializerEvent>False</XmlSerializerEvent>
<BaseClassName>EntityBase</BaseClassName>
<UseBaseClass>False</UseBaseClass>
<GenBaseClass>False</GenBaseClass>
<CustomUsings></CustomUsings>
<AttributesToExlude></AttributesToExlude>
</auto-generated>
<?xml version="1.0" encoding="utf-8"?>
<auto-generated>
<NameSpace>Negocio</NameSpace>
<Collection>List</Collection>
<codeType>CSharp</codeType>
<EnableDataBinding>False</EnableDataBinding>
<GenerateCloneMethod>False</GenerateCloneMethod>
<GenerateDataContracts>False</GenerateDataContracts>
<DataMemberNameArg>OnlyIfDifferent</DataMemberNameArg>
<DataMemberOnXmlIgnore>False</DataMemberOnXmlIgnore>
<CodeBaseTag>Net40</CodeBaseTag>
<InitializeFields>All</InitializeFields>
<GenerateUnusedComplexTypes>True</GenerateUnusedComplexTypes>
<GenerateUnusedSimpleTypes>True</GenerateUnusedSimpleTypes>
<GenerateXMLAttributes>True</GenerateXMLAttributes>
<OrderXMLAttrib>False</OrderXMLAttrib>
<EnableLazyLoading>False</EnableLazyLoading>
<VirtualProp>False</VirtualProp>
<PascalCase>False</PascalCase>
<AutomaticProperties>True</AutomaticProperties>
<PropNameSpecified>None</PropNameSpecified>
<PrivateFieldName>StartWithUnderscore</PrivateFieldName>
<PrivateFieldNamePrefix></PrivateFieldNamePrefix>
<EnableRestriction>False</EnableRestriction>
<RestrictionMaxLenght>False</RestrictionMaxLenght>
<RestrictionRegEx>False</RestrictionRegEx>
<RestrictionRange>False</RestrictionRange>
<ValidateProperty>False</ValidateProperty>
<ClassNamePrefix></ClassNamePrefix>
<ClassLevel>Public</ClassLevel>
<PartialClass>True</PartialClass>
<ClassesInSeparateFiles>False</ClassesInSeparateFiles>
<ClassesInSeparateFilesDir></ClassesInSeparateFilesDir>
<TrackingChangesEnable>False</TrackingChangesEnable>
<GenTrackingClasses>False</GenTrackingClasses>
<HidePrivateFieldInIDE>False</HidePrivateFieldInIDE>
<EnableSummaryComment>False</EnableSummaryComment>
<EnableAppInfoSettings>False</EnableAppInfoSettings>
<EnableExternalSchemasCache>False</EnableExternalSchemasCache>
<EnableDebug>False</EnableDebug>
<EnableWarn>False</EnableWarn>
<ExcludeImportedTypes>True</ExcludeImportedTypes>
<ExpandNesteadAttributeGroup>False</ExpandNesteadAttributeGroup>
<CleanupCode>False</CleanupCode>
<EnableXmlSerialization>False</EnableXmlSerialization>
<SerializeMethodName>Serialize</SerializeMethodName>
<DeserializeMethodName>Deserialize</DeserializeMethodName>
<SaveToFileMethodName>SaveToFile</SaveToFileMethodName>
<LoadFromFileMethodName>LoadFromFile</LoadFromFileMethodName>
<EnableEncoding>False</EnableEncoding>
<EnableXMLIndent>False</EnableXMLIndent>
<IndentChar>Indent2Space</IndentChar>
<NewLineAttr>False</NewLineAttr>
<OmitXML>False</OmitXML>
<Encoder>UTF8</Encoder>
<Serializer>XmlSerializer</Serializer>
<sspNullable>False</sspNullable>
<sspString>False</sspString>
<sspCollection>False</sspCollection>
<sspComplexType>False</sspComplexType>
<sspSimpleType>False</sspSimpleType>
<sspEnumType>False</sspEnumType>
<XmlSerializerEvent>False</XmlSerializerEvent>
<BaseClassName>EntityBase</BaseClassName>
<UseBaseClass>False</UseBaseClass>
<GenBaseClass>False</GenBaseClass>
<CustomUsings></CustomUsings>
<AttributesToExlude></AttributesToExlude>
</auto-generated>
If i remove the redefine part on SuministroInformacion.xsd, the generation ends without problem.
Best regards,
Foltak
I think I have enough information to provide an answer now.
Diagnosis
This simple type definition in
SuministroInformacion.xsdlooks invalid to me. The base type could resolve to sii:VersionSiiType fromCabecera.xsd, or it could resolve to the redefined version inSuministroInformacion.xsd(which would be a recursive definition, and is probably the cause of the infinite loop).xsd2code++ should validate the XSD before it tries to generate code from it, so in my opinion that's a bug in xsd2code++.
Alternative solution to avoid the defect
As I said in the comments, xs:redefine should only be used when there is no alternative. In this case, there is a very good alternative. Object-oriented languages allow a type to be 'abstract'. So does XML Schema. Object-oriented languages allow type inheritance. So does XML Schema. I think you can achieve all of your goals without triggering this defect in xsd2code++.
Step 1: For each type in Cabecera.xsd that should always be overridden, define it as abstract using
abstract="true"in the type definition.Step 2: For each xs:redefine, remove the redefine and change the type name (or if you prefer, change the targetNamespace of the schema and leave the name unchanged). Add the enums or other facets exactly as before using
<xs:restriction>Obviously, this will change the name or namespace of the sub-types. You were probably trying to avoid that by using xs:redefine. But you should avoid having two or more type definitions with identical names and different meanings. Think again about your real requirements.
If you need to refer to a specific sub-type in your other XSDs, you can do that easily. But if you want the other XSDs to refer to a single simple type then