2017-02-17 27 views
15

System.Xml.Serialization.XmlCodeExporter tạo mã (dưới dạng mã CodeDom) từ lược đồ XSD. Nhưng nó có nó với một số quirks. Ví dụ một yếu tố bắt buộc:Các loại XmlCodeExporter và nullable

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

tôi sẽ mong đợi điều này để tạo ra một thành viên mã tương ứng của loại Nullable<decimal>, nhưng nó thực sự tạo ra một thành viên của loại decimal, và sau đó một riêng biệt SomethingSpecified lĩnh vực cần được toggled riêng để chỉ một giá trị null. Điều này có lẽ vì thư viện là từ trước khi giới thiệu các kiểu nullable, nhưng nó dẫn đến mã thực sự bất tiện.

Có thể điều chỉnh việc tạo mã này hay không hoặc có công cụ thay thế nào tạo mã tốt hơn trong trường hợp này không?

Chỉnh sửa: Tôi biết tôi có thể sửa đổi giản đồ và thêm nillable='true', nhưng tôi không muốn thay đổi lược đồ để làm việc xung quanh các giới hạn của việc tạo mã.

+0

Thử công cụ Xsd2Code. Tôi sử dụng nó rộng rãi thay vì xsd.exe. Thật không may tôi không thể nói cho bạn biết chắc chắn rằng vấn đề cụ thể mà bạn đề cập được giải quyết ở đó. – Evk

+0

Bạn đã thử sử dụng 'nillable = 'true'' thay vì min/max xảy ra? – tchrikch

+0

@Evk: Xsd2Code dường như sử dụng XmlCodeExporter dưới mui xe và dường như có cùng một vấn đề. – JacquesB

Trả lời

13

Bài viết Writing your own XSD.exe bởi Mike Hadlow cung cấp khung cơ bản để tạo phiên bản xsd.exe của riêng bạn. Nó có các bước sau:

  1. Nhập các lược đồ với XmlSchema.Read()XmlSchemaImporter.

  2. Tạo. Loại Net và (các) thuộc tính để tạo bằng cách sử dụng XmlCodeExporter.

  3. Tinh chỉnh các loại và thuộc tính được tạo như mong muốn.

    Tại đây, bạn sẽ muốn xóa thuộc tính xxxSpecified được tạo và quảng bá các thuộc tính "thực" tương ứng của chúng thành giá trị rỗng.

  4. Tạo mã cuối cùng bằng cách sử dụng CSharpCodeProvider.

Sử dụng khuôn khổ này, và bằng cách thực nghiệm xác định loại đang thực sự tạo ra bởi XmlCodeExporter sử dụng một trình gỡ lỗi, tôi đã tạo ra sau CustomXsdCodeGenerator:

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) 
    { 
    } 
} 

Để kiểm tra nó, tôi tạo ra các loại sau đây:

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; } 
    } 
} 

Sử dụng chung chung xsd.exe Tôi đã tạo giản đồ sau từ chúng:

<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> 

Và, sử dụng sơ đồ này, tôi tái sinh C# lớp dưới, sử dụng CustomXsdCodeGenerator với promoteToNullable = trueNamespace = "Question42295155":

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; 
      } 
     } 
    } 
} 

Chú ý rằng:

  • Không có thuộc tính kết thúc bằng tên Specified.

  • Các thuộc tính Something, SomeEnumSomeDateTime đã trở thành vô hiệu.

  • Đã vô hiệu hóa public decimal? SomeNullable { get; set; } các chuyến đi khứ hồi đến public System.Nullable<decimal> SomeNullable thay vì không thành công bằng cách trở thành một số vô hiệu kép đáng kinh ngạc System.Nullable<System.Nullable<decimal>>.

sau đó tôi tạo ra XML sau đây từ ban đầu RootClass:

<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> 

Và đã có thể deserialize thành công nó vào lớp tạo Question42295155.RootClass mà không mất dữ liệu.

Lưu ý - mã này được kiểm tra nhẹ. Tôi có thể kiểm tra lại với lược đồ mẫu nếu bạn muốn cung cấp.

Để biết thêm thông tin, hãy xem Code Generation in the .NET Framework Using XML Schema.

+0

Làm việc tuyệt vời, cảm ơn! – JacquesB

+0

Làm việc tốt với lời giải thích tốt !!!!! – csharpbd

Các vấn đề liên quan