From 5d1eb8a0802a076022912b47e770790bc6211c72 Mon Sep 17 00:00:00 2001 From: Michael Ganss Date: Fri, 16 Oct 2015 16:33:09 +0200 Subject: [PATCH] Do not duplicate attributes/elements on restricted derived classes Do not duplicate Text property for mixed elements which have a base class that is also mixed Fix bug in IsArray --- README.md | 1 + XmlSchemaClassGenerator/Generator.cs | 25 +++++++++++++++++-------- XmlSchemaClassGenerator/TypeModel.cs | 22 ++++++++++++++++++---- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 71b7b212..484f1f93 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ Unsupported: * Some restriction types * Recursive choices and choices whose elements have minOccurs > 0 (see [below](#choice)) * Possible name clashes and invalid identifiers when names contain non-alphanumeric characters +* Groups with maxOccurs > 0 Usage ----- diff --git a/XmlSchemaClassGenerator/Generator.cs b/XmlSchemaClassGenerator/Generator.cs index 024e8d3d..92225e49 100644 --- a/XmlSchemaClassGenerator/Generator.cs +++ b/XmlSchemaClassGenerator/Generator.cs @@ -497,8 +497,11 @@ private TypeModel CreateTypeModel(Uri source, XmlSchemaAnnotated type, XmlQualif { if (complexType.ContentModel.Content is XmlSchemaComplexContentExtension) particle = ((XmlSchemaComplexContentExtension)complexType.ContentModel.Content).Particle; - else if (complexType.ContentModel.Content is XmlSchemaComplexContentRestriction) - particle = ((XmlSchemaComplexContentRestriction)complexType.ContentModel.Content).Particle; + + // If it's a restriction, do not duplicate elements on the derived class, they're already in the base class. + // See https://msdn.microsoft.com/en-us/library/f3z3wh0y.aspx + //else if (complexType.ContentModel.Content is XmlSchemaComplexContentRestriction) + // particle = ((XmlSchemaComplexContentRestriction)complexType.ContentModel.Content).Particle; } else particle = complexType.ContentTypeParticle; @@ -520,15 +523,21 @@ private TypeModel CreateTypeModel(Uri source, XmlSchemaAnnotated type, XmlQualif attributes = ((XmlSchemaComplexContentExtension)complexType.ContentModel.Content).Attributes; else if (complexType.ContentModel.Content is XmlSchemaSimpleContentExtension) attributes = ((XmlSchemaSimpleContentExtension)complexType.ContentModel.Content).Attributes; - else if (complexType.ContentModel.Content is XmlSchemaComplexContentRestriction) - attributes = ((XmlSchemaComplexContentRestriction)complexType.ContentModel.Content).Attributes; - else if (complexType.ContentModel.Content is XmlSchemaSimpleContentRestriction) - attributes = ((XmlSchemaSimpleContentRestriction)complexType.ContentModel.Content).Attributes; + + // If it's a restriction, do not duplicate attributes on the derived class, they're already in the base class. + // See https://msdn.microsoft.com/en-us/library/f3z3wh0y.aspx + //else if (complexType.ContentModel.Content is XmlSchemaComplexContentRestriction) + // attributes = ((XmlSchemaComplexContentRestriction)complexType.ContentModel.Content).Attributes; + //else if (complexType.ContentModel.Content is XmlSchemaSimpleContentRestriction) + // attributes = ((XmlSchemaSimpleContentRestriction)complexType.ContentModel.Content).Attributes; } else attributes = complexType.Attributes; - var attributeProperties = CreatePropertiesForAttributes(source, classModel, attributes.Cast()); - classModel.Properties.AddRange(attributeProperties); + if (attributes != null) + { + var attributeProperties = CreatePropertiesForAttributes(source, classModel, attributes.Cast()); + classModel.Properties.AddRange(attributeProperties); + } if (GenerateInterfaces) { diff --git a/XmlSchemaClassGenerator/TypeModel.cs b/XmlSchemaClassGenerator/TypeModel.cs index caaf6652..451d38f1 100644 --- a/XmlSchemaClassGenerator/TypeModel.cs +++ b/XmlSchemaClassGenerator/TypeModel.cs @@ -207,6 +207,19 @@ public ClassModel(GeneratorConfiguration configuration) DerivedTypes = new List(); } + public IEnumerable AllBaseClasses + { + get + { + var baseClass = BaseClass as ClassModel; + while (baseClass != null) + { + yield return baseClass; + baseClass = baseClass.BaseClass as ClassModel; + } + } + } + public override CodeTypeDeclaration Generate() { var classDeclaration = base.Generate(); @@ -326,7 +339,7 @@ public override CodeTypeDeclaration Generate() foreach (var property in Properties) property.AddMembersTo(classDeclaration, EnableDataBinding); - if (IsMixed && (BaseClass == null || BaseClass is ClassModel)) + if (IsMixed && (BaseClass == null || (BaseClass is ClassModel && !AllBaseClasses.Any(b => b.IsMixed)))) { var text = new CodeMemberField(typeof(string), "Text"); // hack to generate automatic property @@ -517,10 +530,11 @@ private bool IsArray { get { - return !IsCollection && !IsAttribute && TypeClassModel != null && TypeClassModel.TotalProperties == 1 + return !IsCollection && !IsAttribute && TypeClassModel != null + && TypeClassModel.BaseClass == null + && TypeClassModel.Properties.Count == 1 && !TypeClassModel.Properties[0].IsAttribute && !TypeClassModel.Properties[0].IsAny - && TypeClassModel.Properties[0].IsCollection - && TypeClassModel.BaseClass == null; + && TypeClassModel.Properties[0].IsCollection; } }