xsd2Code++重新定义标签反序列化不起作用。

问题描述 投票:0回答:2

我试图在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>

生成选项如下。

  • Cabecera.xsd.SuministroInformacion.xsd:
  • <?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:
  • <?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

    xml xsd xsd2code
    2个回答
    0
    投票

    我想我现在有足够的信息来提供一个答案。

    诊断

    这个简单的类型定义在 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 引用一个简单的类型,那么

    • 指定基本类型
    • 在你的XML文档中添加一个xsi:type属性来确定你要验证的子类型。欢迎咨询更多关于这个技术的信息。

    0
    投票

    经过对xsd2code++源码的分析和调试,确实存在一个无限循环,这是由XmlSchemaImporter类的ImportTypeMapping方法引起的。

    因此,问题出在微软框架本身。在xsd2code++中,也许可以通过建立一个新的模式,整合新的定义来解决这种情况。这似乎是一个相当复杂的算法,但似乎是可以实现的。

    这个问题已经提交给了xsd2code++的支持团队,以便找到解决方案。

    同样使用XmlSchemaImporter的xsd.exe也会导致无限循环。

    © www.soinside.com 2019 - 2024. All rights reserved.