我试图在Visual Studio 2019上用xsd:redefine标签从xsd定义生成一些类,但在Xsd2Code++ 5.0.0.47版本上进入了无限循环。
这是我的例子的简化。
文件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>
文件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>
生成选项如下。
<?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>
如果我把SuministroInformacion.xsd上的redefine部分去掉,生成就会顺利结束。问候,Foltak
我想我现在有足够的信息来提供一个答案。
诊断
这个简单的类型定义在 SuministroInformacion.xsd
在我看来是无效的。基本类型可以解析为sii:VersionSiiType从 Cabecera.xsd
中的重新定义的版本,或者它可以解析为在 SuministroInformacion.xsd
(这将是一个递归定义,可能是无限循环的原因)。
<simpleType name="VersionSiiType">
<restriction base="sii:VersionSiiType">
<enumeration value="1.0"/>
</restriction>
xsd2code++应该在尝试从XSD中生成代码之前验证XSD,所以在我看来这是xsd2code++的一个bug。
避免该缺陷的替代解决方案
正如我在评论中所说的,xs:redefine只应该在没有其他选择的情况下使用。在这种情况下,有一个非常好的选择。面向对象的语言允许一个类型是 "抽象 "的。XML Schema也是如此. 面向对象的语言允许类型继承。XML Schema也是如此. 我认为你可以在不触发xsd2code++中的这个缺陷的情况下实现你所有的目标。
第1步:对于Cabecera.xsd中的每一个类型,应该 始终 覆盖,将其定义为抽象的,使用 abstract="true"
的类型定义中。
步骤2:对于每个xs:redefine,删除redefine并更改类型名称(或者如果你喜欢,更改模式的targetNamespace并保持名称不变)。添加枚举或其他方面的内容,就像之前使用 <xs:restriction>
很明显,这将改变子类型的名称或命名空间。您可能是想通过使用 xs:redefine 来避免这种情况。但您应该避免使用两个或多个类型定义,并使用 一模一样 名称和不同的含义。再想想你真正的需求。
如果您需要在其他 XSD 中引用一个特定的子类型,您可以很容易地做到这一点。但是,如果您希望其他 XSD 引用一个简单的类型,那么
经过对xsd2code++源码的分析和调试,确实存在一个无限循环,这是由XmlSchemaImporter类的ImportTypeMapping方法引起的。
因此,问题出在微软框架本身。在xsd2code++中,也许可以通过建立一个新的模式,整合新的定义来解决这种情况。这似乎是一个相当复杂的算法,但似乎是可以实现的。
这个问题已经提交给了xsd2code++的支持团队,以便找到解决方案。
同样使用XmlSchemaImporter的xsd.exe也会导致无限循环。