2017-02-17 1 views
15

System.Xml.Serialization.XmlCodeExporter은 XSD 스키마에서 코드 CodeDom 형식의 코드를 생성합니다. 그러나 그것은 몇 가지 단점을 가지고 있습니다. 예를 들어 선택 요소 :XmlCodeExporter 및 null 가능 형식

<xs:element name="Something" type="xs:decimal" minOccurs="0" maxOccurs="1"/> 

내가이 유형 Nullable<decimal>의 해당 코드 멤버를 생성하는 기대하지만, 실제로 형 decimal의 멤버를 만든 다음 개별적으로 전환해야한다 별도의 SomethingSpecified 필드를 나타냅니다 null 치 이것은 라이브러리가 null 가능 유형이 도입되기 전에 있었던 것이므로 실제로는 불편한 코드로 이어집니다.

이 코드 생성을 조정할 수 있습니까? 아니면 더 나은 코드를 생성 할 수있는 대체 도구가 있습니까?

편집 : 스키마를 수정하고 nillable='true'을 추가 할 수 있지만 코드 생성 제한을 해결하기 위해 스키마를 변경하고 싶지 않습니다.

+0

Xsd2Code 도구를 사용해보십시오. xsd.exe 대신 광범위하게 사용했습니다. 불행히도 내가 말한 구체적인 문제가 해결되었는지 확실하게 말할 수는 없습니다. – Evk

+0

min/max 대신'nillable = 'true'를 사용 해봤습니까? – tchrikch

+0

@Evk : Xsd2Code는 XmlCodeExporter를 사용하는 것으로 보이며 같은 문제가있는 것 같습니다. – JacquesB

답변

13

Writing your own XSD.exe Mike Hadlow가 작성한 xsd.exe의 고유 한 버전을 만드는 데 필요한 기본 프레임 워크를 제공합니다. 그것은 다음 단계가 있습니다 XmlSchema.Read()XmlSchemaImporter

  1. 가져 오기 스키마를.

  2. XmlCodeExporter을 사용하여 .Net 유형 및 속성을 생성하십시오.

  3. 원하는대로 생성 된 유형 및 속성을 조정하십시오..

    여기서 생성 된 xxxSpecified 속성을 제거하고 해당 "실제"속성을 null로 승격 할 수 있습니다.

  4. CSharpCodeProvider을 사용하여 최종 코드를 생성하십시오.

    public class CustomXsdCodeGenerator : CustomXsdCodeGeneratorBase 
    { 
        readonly bool promoteToNullable; 
    
        public CustomXsdCodeGenerator(string Namespace, bool promoteToNullable) : base(Namespace) 
        { 
         this.promoteToNullable = promoteToNullable; 
        } 
    
        protected override void ModifyGeneratedCodeTypeDeclaration(CodeTypeDeclaration codeType, CodeNamespace codeNamespace) 
        { 
         RemoveSpecifiedProperties(codeNamespace, promoteToNullable); 
         base.ModifyGeneratedCodeTypeDeclaration(codeType, codeNamespace); 
        } 
    
        private static void RemoveSpecifiedProperties(CodeNamespace codeNamespace, bool promoteToNullable) 
        { 
         foreach (CodeTypeDeclaration codeType in codeNamespace.Types) 
         { 
          RemoveSpecifiedProperties(codeType, codeNamespace, promoteToNullable); 
         } 
        } 
    
        private static void RemoveSpecifiedProperties(CodeTypeDeclaration codeType, CodeNamespace codeNamespace, bool promoteToNullable) 
        { 
         var toRemove = new List<CodeTypeMember>(); 
    
         foreach (var property in codeType.Members.OfType<CodeMemberProperty>()) 
         { 
          CodeMemberField backingField; 
          CodeMemberProperty specifiedProperty; 
          if (!property.TryGetBackingFieldAndSpecifiedProperty(codeType, out backingField, out specifiedProperty)) 
           continue; 
          var specifiedField = specifiedProperty.GetBackingField(codeType); 
          if (specifiedField == null) 
           continue; 
          toRemove.Add(specifiedProperty); 
          toRemove.Add(specifiedField); 
    
          if (promoteToNullable) 
          { 
           // Do not do this for attributes 
           if (property.CustomAttributes.Cast<CodeAttributeDeclaration>().Any(a => a.AttributeType.BaseType == typeof(System.Xml.Serialization.XmlAttributeAttribute).FullName)) 
            continue; 
           var typeRef = property.Type; 
           if (typeRef.ArrayRank > 0) 
            // An array - not a reference type. 
            continue; 
    
           // OK, two possibilities here: 
           // 1) The property might reference some system type such as DateTime or decimal 
           // 2) The property might reference some type being defined such as an enum or struct. 
    
           var type = Type.GetType(typeRef.BaseType); 
           if (type != null) 
           { 
            if (!type.IsClass) 
            { 
             if (type == typeof(Nullable<>)) 
              // Already nullable 
              continue; 
             else if (!type.IsGenericTypeDefinition && (type.IsValueType || type.IsEnum) && Nullable.GetUnderlyingType(type) == null) 
             { 
              var nullableType = typeof(Nullable<>).MakeGenericType(type); 
              var newRefType = new CodeTypeReference(nullableType); 
              property.Type = newRefType; 
              backingField.Type = newRefType; 
             } 
            } 
           } 
           else 
           { 
            var generatedType = codeNamespace.FindCodeType(typeRef); 
            if (generatedType != null) 
            { 
             if (generatedType.IsStruct || generatedType.IsEnum) 
             { 
              var newRefType = new CodeTypeReference(typeof(Nullable<>).FullName, typeRef); 
              property.Type = newRefType; 
              backingField.Type = newRefType; 
             } 
            } 
           } 
          } 
         } 
         foreach (var member in toRemove) 
         { 
          codeType.Members.Remove(member); 
         } 
        } 
    } 
    
    public static class CodeNamespaceExtensions 
    { 
        public static CodeTypeDeclaration FindCodeType(this CodeNamespace codeNamespace, CodeTypeReference reference) 
        { 
         if (codeNamespace == null) 
          throw new ArgumentNullException(); 
         if (reference == null) 
          return null; 
         CodeTypeDeclaration foundType = null; 
         foreach (CodeTypeDeclaration codeType in codeNamespace.Types) 
         { 
          if (codeType.Name == reference.BaseType) 
          { 
           if (foundType == null) 
            foundType = codeType; 
           else if (foundType != codeType) 
           { 
            foundType = null; 
            break; 
           } 
          } 
         } 
         return foundType; 
        } 
    } 
    
    public static class CodeMemberPropertyExtensions 
    { 
        public static bool TryGetBackingFieldAndSpecifiedProperty(this CodeMemberProperty property, CodeTypeDeclaration codeType, 
         out CodeMemberField backingField, out CodeMemberProperty specifiedProperty) 
        { 
         if (property == null) 
         { 
          backingField = null; 
          specifiedProperty = null; 
          return false; 
         } 
    
         if ((backingField = property.GetBackingField(codeType)) == null) 
         { 
          specifiedProperty = null; 
          return false; 
         } 
    
         specifiedProperty = null; 
         var specifiedName = property.Name + "Specified"; 
         foreach (var p in codeType.Members.OfType<CodeMemberProperty>()) 
         { 
          if (p.Name == specifiedName) 
          { 
           // Make sure the property is marked as XmlIgnore (there might be a legitimate, serializable property 
           // named xxxSpecified). 
           if (!p.CustomAttributes.Cast<CodeAttributeDeclaration>().Any(a => a.AttributeType.BaseType == typeof(System.Xml.Serialization.XmlIgnoreAttribute).FullName)) 
            continue; 
           if (specifiedProperty == null) 
            specifiedProperty = p; 
           else if (specifiedProperty != p) 
           { 
            specifiedProperty = null; 
            break; 
           } 
          } 
         } 
         if (specifiedProperty == null) 
          return false; 
         if (specifiedProperty.GetBackingField(codeType) == null) 
          return false; 
         return true; 
        } 
    
        public static CodeMemberField GetBackingField(this CodeMemberProperty property, CodeTypeDeclaration codeType) 
        { 
         if (property == null) 
          return null; 
    
         CodeMemberField returnedField = null; 
         foreach (var statement in property.GetStatements.OfType<CodeMethodReturnStatement>()) 
         { 
          var expression = statement.Expression as CodeFieldReferenceExpression; 
          if (expression == null) 
           return null; 
          if (!(expression.TargetObject is CodeThisReferenceExpression)) 
           return null; 
          var fieldName = expression.FieldName; 
          foreach (var field in codeType.Members.OfType<CodeMemberField>()) 
          { 
           if (field.Name == fieldName) 
           { 
            if (returnedField == null) 
             returnedField = field; 
            else if (returnedField != field) 
             return null; 
           } 
          } 
         } 
    
         return returnedField; 
        } 
    } 
    
    public abstract class CustomXsdCodeGeneratorBase 
    { 
        // This base class adapted from http://mikehadlow.blogspot.com/2007/01/writing-your-own-xsdexe.html 
    
        readonly string Namespace; 
    
        public CustomXsdCodeGeneratorBase(string Namespace) 
        { 
         this.Namespace = Namespace; 
        } 
    
        public void XsdToClassTest(IEnumerable<string> xsds, TextWriter codeWriter) 
        { 
         XsdToClassTest(xsds.Select(xsd => (Func<TextReader>)(() => new StringReader(xsd))), codeWriter); 
        } 
    
        public void XsdToClassTest(IEnumerable<Func<TextReader>> xsds, TextWriter codeWriter) 
        { 
         var schemas = new XmlSchemas(); 
    
         foreach (var getReader in xsds) 
         { 
          using (var reader = getReader()) 
          { 
           var xsd = XmlSchema.Read(reader, null); 
           schemas.Add(xsd); 
          } 
         } 
    
         schemas.Compile(null, true); 
         var schemaImporter = new XmlSchemaImporter(schemas); 
    
         var maps = new List<XmlTypeMapping>(); 
         foreach (XmlSchema xsd in schemas) 
         { 
          foreach (XmlSchemaType schemaType in xsd.SchemaTypes.Values) 
          { 
           maps.Add(schemaImporter.ImportSchemaType(schemaType.QualifiedName)); 
          } 
          foreach (XmlSchemaElement schemaElement in xsd.Elements.Values) 
          { 
           maps.Add(schemaImporter.ImportTypeMapping(schemaElement.QualifiedName)); 
          } 
         } 
    
         // create the codedom 
         var codeNamespace = new CodeNamespace(this.Namespace); 
         var codeExporter = new XmlCodeExporter(codeNamespace); 
         foreach (XmlTypeMapping map in maps) 
         { 
          codeExporter.ExportTypeMapping(map); 
         } 
    
         ModifyGeneratedNamespace(codeNamespace); 
    
         // Check for invalid characters in identifiers 
         CodeGenerator.ValidateIdentifiers(codeNamespace); 
    
         // output the C# code 
         var codeProvider = new CSharpCodeProvider(); 
         codeProvider.GenerateCodeFromNamespace(codeNamespace, codeWriter, new CodeGeneratorOptions()); 
        } 
    
        protected virtual void ModifyGeneratedNamespace(CodeNamespace codeNamespace) 
        { 
         foreach (CodeTypeDeclaration codeType in codeNamespace.Types) 
         { 
          ModifyGeneratedCodeTypeDeclaration(codeType, codeNamespace); 
         } 
        } 
    
        protected virtual void ModifyGeneratedCodeTypeDeclaration(CodeTypeDeclaration codeType, CodeNamespace codeNamespace) 
        { 
        } 
    } 
    

    그것을 테스트하려면, 나는 다음과 같은 유형의 생성 :

이 프레임 워크를 사용하고, 실험적으로 디버거를 사용 XmlCodeExporter에 의해 종류가 실제로 생성되는 것을 결정함으로써, 나는이 CustomXsdCodeGenerator 다음 생성

namespace SampleClasses 
{ 
    public class SimleSampleClass 
    { 
     [XmlElement] 
     public decimal Something { get; set; } 

     [XmlIgnore] 
     public bool SomethingSpecified { get; set; } 
    } 

    [XmlRoot("RootClass")] 
    public class RootClass 
    { 
     [XmlArray] 
     [XmlArrayItem("SampleClass")] 
     public List<SampleClass> SampleClasses { get; set; } 
    } 

    [XmlRoot("SampleClass")] 
    public class SampleClass 
    { 
     [XmlAttribute] 
     public long Id { get; set; } 

     public decimal Something { get; set; } 

     [XmlIgnore] 
     public bool SomethingSpecified { get; set; } 

     public SomeEnum SomeEnum { get; set; } 

     [XmlIgnore] 
     public bool SomeEnumSpecified { get; set; } 

     public string SomeString { get; set; } 

     [XmlIgnore] 
     public bool SomeStringSpecified { get; set; } 

     public decimal? SomeNullable { get; set; } 

     [XmlIgnore] 
     public bool SomeNullableSpecified { get; set; } 

     public DateTime SomeDateTime { get; set; } 

     [XmlIgnore] 
     public bool SomeDateTimeSpecified { get; set; } 

     // https://stackoverflow.com/questions/3280362/most-elegant-xml-serialization-of-color-structure 

     [XmlElement(Type = typeof(XmlColor))] 
     public Color MyColor { get; set; } 

     [XmlIgnore] 
     public bool MyColorSpecified { get; set; } 
    } 

    public enum SomeEnum 
    { 
     DefaultValue, 
     FirstValue, 
     SecondValue, 
     ThirdValue, 
    } 

    // https://stackoverflow.com/questions/3280362/most-elegant-xml-serialization-of-color-structure 
    public struct XmlColor 
    { 
     private Color? color_; 

     private Color Color 
     { 
      get 
      { 
       return color_ ?? Color.Black; 
      } 
      set 
      { 
       color_ = value; 
      } 
     } 

     public XmlColor(Color c) { color_ = c; } 

     public Color ToColor() 
     { 
      return Color; 
     } 

     public void FromColor(Color c) 
     { 
      Color = c; 
     } 

     public static implicit operator Color(XmlColor x) 
     { 
      return x.ToColor(); 
     } 

     public static implicit operator XmlColor(Color c) 
     { 
      return new XmlColor(c); 
     } 

     [XmlAttribute] 
     public string Web 
     { 
      get { return ColorTranslator.ToHtml(Color); } 
      set 
      { 
       try 
       { 
        if (Alpha == 0xFF) // preserve named color value if possible 
         Color = ColorTranslator.FromHtml(value); 
        else 
         Color = Color.FromArgb(Alpha, ColorTranslator.FromHtml(value)); 
       } 
       catch (Exception) 
       { 
        Color = Color.Black; 
       } 
      } 
     } 

     [XmlAttribute] 
     public byte Alpha 
     { 
      get { return Color.A; } 
      set 
      { 
       if (value != Color.A) // avoid hammering named color if no alpha change 
        Color = Color.FromArgb(value, Color); 
      } 
     } 

     public bool ShouldSerializeAlpha() { return Alpha < 0xFF; } 
    } 
} 

일반 xsd.exe을 사용하여 다음 스키마를 생성했습니다.

<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="SimleSampleClass" nillable="true" type="SimleSampleClass" /> 
    <xs:complexType name="SimleSampleClass"> 
    <xs:sequence> 
     <xs:element minOccurs="0" maxOccurs="1" name="Something" type="xs:decimal" /> 
    </xs:sequence> 
    </xs:complexType> 
    <xs:element name="RootClass" nillable="true" type="RootClass" /> 
    <xs:complexType name="RootClass"> 
    <xs:sequence> 
     <xs:element minOccurs="0" maxOccurs="1" name="SampleClasses" type="ArrayOfSampleClass" /> 
    </xs:sequence> 
    </xs:complexType> 
    <xs:complexType name="ArrayOfSampleClass"> 
    <xs:sequence> 
     <xs:element minOccurs="0" maxOccurs="unbounded" name="SampleClass" nillable="true" type="SampleClass" /> 
    </xs:sequence> 
    </xs:complexType> 
    <xs:complexType name="SampleClass"> 
    <xs:sequence> 
     <xs:element minOccurs="0" maxOccurs="1" name="Something" type="xs:decimal" /> 
     <xs:element minOccurs="0" maxOccurs="1" name="SomeEnum" type="SomeEnum" /> 
     <xs:element minOccurs="0" maxOccurs="1" name="SomeString" type="xs:string" /> 
     <xs:element minOccurs="0" maxOccurs="1" name="SomeNullable" nillable="true" type="xs:decimal" /> 
     <xs:element minOccurs="0" maxOccurs="1" name="SomeDateTime" type="xs:dateTime" /> 
     <xs:element minOccurs="0" maxOccurs="1" name="MyColor" type="XmlColor" /> 
    </xs:sequence> 
    <xs:attribute name="Id" type="xs:long" use="required" /> 
    </xs:complexType> 
    <xs:simpleType name="SomeEnum"> 
    <xs:restriction base="xs:string"> 
     <xs:enumeration value="DefaultValue" /> 
     <xs:enumeration value="FirstValue" /> 
     <xs:enumeration value="SecondValue" /> 
     <xs:enumeration value="ThirdValue" /> 
    </xs:restriction> 
    </xs:simpleType> 
    <xs:complexType name="XmlColor"> 
    <xs:attribute name="Web" type="xs:string" /> 
    <xs:attribute name="Alpha" type="xs:unsignedByte" /> 
    </xs:complexType> 
    <xs:element name="SampleClass" nillable="true" type="SampleClass" /> 
    <xs:element name="SomeEnum" type="SomeEnum" /> 
    <xs:element name="XmlColor" type="XmlColor" /> 
</xs:schema> 

는 그리고,이 스키마를 사용하여, 나는 promoteToNullable = trueNamespace = "Question42295155"CustomXsdCodeGenerator를 사용하여 다음 C# 클래스를 재생 :

namespace Question42295155 { 


    /// <remarks/> 
    [System.CodeDom.Compiler.GeneratedCodeAttribute("XsdToClassTest", "1.0.0.0")] 
    [System.SerializableAttribute()] 
    [System.Diagnostics.DebuggerStepThroughAttribute()] 
    [System.ComponentModel.DesignerCategoryAttribute("code")] 
    [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=true)] 
    public partial class SimleSampleClass { 

     private System.Nullable<decimal> somethingField; 

     /// <remarks/> 
     public System.Nullable<decimal> Something { 
      get { 
       return this.somethingField; 
      } 
      set { 
       this.somethingField = value; 
      } 
     } 
    } 

    /// <remarks/> 
    [System.CodeDom.Compiler.GeneratedCodeAttribute("XsdToClassTest", "1.0.0.0")] 
    [System.SerializableAttribute()] 
    [System.Diagnostics.DebuggerStepThroughAttribute()] 
    [System.ComponentModel.DesignerCategoryAttribute("code")] 
    [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=true)] 
    public partial class SampleClass { 

     private System.Nullable<decimal> somethingField; 

     private System.Nullable<SomeEnum> someEnumField; 

     private string someStringField; 

     private System.Nullable<decimal> someNullableField; 

     private System.Nullable<System.DateTime> someDateTimeField; 

     private XmlColor myColorField; 

     private long idField; 

     /// <remarks/> 
     public System.Nullable<decimal> Something { 
      get { 
       return this.somethingField; 
      } 
      set { 
       this.somethingField = value; 
      } 
     } 

     /// <remarks/> 
     public System.Nullable<SomeEnum> SomeEnum { 
      get { 
       return this.someEnumField; 
      } 
      set { 
       this.someEnumField = value; 
      } 
     } 

     /// <remarks/> 
     public string SomeString { 
      get { 
       return this.someStringField; 
      } 
      set { 
       this.someStringField = value; 
      } 
     } 

     /// <remarks/> 
     [System.Xml.Serialization.XmlElementAttribute(IsNullable=true)] 
     public System.Nullable<decimal> SomeNullable { 
      get { 
       return this.someNullableField; 
      } 
      set { 
       this.someNullableField = value; 
      } 
     } 

     /// <remarks/> 
     public System.Nullable<System.DateTime> SomeDateTime { 
      get { 
       return this.someDateTimeField; 
      } 
      set { 
       this.someDateTimeField = value; 
      } 
     } 

     /// <remarks/> 
     public XmlColor MyColor { 
      get { 
       return this.myColorField; 
      } 
      set { 
       this.myColorField = value; 
      } 
     } 

     /// <remarks/> 
     [System.Xml.Serialization.XmlAttributeAttribute()] 
     public long Id { 
      get { 
       return this.idField; 
      } 
      set { 
       this.idField = value; 
      } 
     } 
    } 

    /// <remarks/> 
    [System.CodeDom.Compiler.GeneratedCodeAttribute("XsdToClassTest", "1.0.0.0")] 
    [System.SerializableAttribute()] 
    [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)] 
    public enum SomeEnum { 

     /// <remarks/> 
     DefaultValue, 

     /// <remarks/> 
     FirstValue, 

     /// <remarks/> 
     SecondValue, 

     /// <remarks/> 
     ThirdValue, 
    } 

    /// <remarks/> 
    [System.CodeDom.Compiler.GeneratedCodeAttribute("XsdToClassTest", "1.0.0.0")] 
    [System.SerializableAttribute()] 
    [System.Diagnostics.DebuggerStepThroughAttribute()] 
    [System.ComponentModel.DesignerCategoryAttribute("code")] 
    [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=true)] 
    public partial class XmlColor { 

     private string webField; 

     private byte alphaField; 

     /// <remarks/> 
     [System.Xml.Serialization.XmlAttributeAttribute()] 
     public string Web { 
      get { 
       return this.webField; 
      } 
      set { 
       this.webField = value; 
      } 
     } 

     /// <remarks/> 
     [System.Xml.Serialization.XmlAttributeAttribute()] 
     public byte Alpha { 
      get { 
       return this.alphaField; 
      } 
      set { 
       this.alphaField = value; 
      } 
     } 
    } 

    /// <remarks/> 
    [System.CodeDom.Compiler.GeneratedCodeAttribute("XsdToClassTest", "1.0.0.0")] 
    [System.SerializableAttribute()] 
    [System.Diagnostics.DebuggerStepThroughAttribute()] 
    [System.ComponentModel.DesignerCategoryAttribute("code")] 
    [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=true)] 
    public partial class RootClass { 

     private SampleClass[] sampleClassesField; 

     /// <remarks/> 
     public SampleClass[] SampleClasses { 
      get { 
       return this.sampleClassesField; 
      } 
      set { 
       this.sampleClassesField = value; 
      } 
     } 
    } 

    /// <remarks/> 
    [System.CodeDom.Compiler.GeneratedCodeAttribute("XsdToClassTest", "1.0.0.0")] 
    [System.SerializableAttribute()] 
    [System.Diagnostics.DebuggerStepThroughAttribute()] 
    [System.ComponentModel.DesignerCategoryAttribute("code")] 
    [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=true)] 
    public partial class ArrayOfSampleClass { 

     private SampleClass[] sampleClassField; 

     /// <remarks/> 
     [System.Xml.Serialization.XmlElementAttribute("SampleClass", IsNullable=true)] 
     public SampleClass[] SampleClass { 
      get { 
       return this.sampleClassField; 
      } 
      set { 
       this.sampleClassField = value; 
      } 
     } 
    } 
} 

공지 것을 :

  • 이름으로 끝나는 어떤 속성이 없습니다 Specified.

  • 등록 정보 Something, SomeEnumSomeDateTime은 Nullable이되었습니다.

  • 오히려 약간 무서운 이중 널 (NULL) System.Nullable<System.Nullable<decimal>> 됨으로써 실패보다 더 public System.Nullable<decimal> SomeNullable에 이미 널 (NULL) public decimal? SomeNullable { get; set; } 왕복.

나는 다음 초기 RootClass에서 다음 XML 생성 :

<RootClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <SampleClasses> 
    <SampleClass Id="10101"> 
     <Something>2.718</Something> 
     <SomeEnum>ThirdValue</SomeEnum> 
     <SomeString>hello</SomeString> 
     <SomeNullable>3.14</SomeNullable> 
     <SomeDateTime>2017-02-28T00:00:00-05:00</SomeDateTime> 
     <MyColor Web="Maroon" /> 
    </SampleClass> 
    </SampleClasses> 
</RootClass> 

을 성공적으로 데이터 손실없이 생성 된 클래스 Question42295155.RootClass에 역 직렬화 할 수 있었다.

참고 -이 코드는 가볍게 테스트되었습니다. 샘플 스키마를 제공하려는 경우 샘플 스키마로 다시 테스트 할 수 있습니다.

자세한 내용은 Code Generation in the .NET Framework Using XML Schema을 참조하십시오.

+0

놀라운 작품, 고마워! – JacquesB

+0

좋은 설명과 함께 좋은 작품 !!!!! – csharpbd