From a9aef9abe76f4d34c151b0db783cb61e11debc27 Mon Sep 17 00:00:00 2001 From: jokokko Date: Wed, 10 Oct 2018 14:15:23 +0300 Subject: [PATCH] For mixed complexTypes, the XmlTextAttribute member should not collide with existing members. XmlTextAttribute member string -> string[] (so no data loss in serializing mixed elements). --- XmlSchemaClassGenerator.Tests/XmlTests.cs | 26 ++++++++++++++++++++++- XmlSchemaClassGenerator/ModelBuilder.cs | 3 ++- XmlSchemaClassGenerator/TypeModel.cs | 11 ++++++++-- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/XmlSchemaClassGenerator.Tests/XmlTests.cs b/XmlSchemaClassGenerator.Tests/XmlTests.cs index b81f706a..7843952c 100644 --- a/XmlSchemaClassGenerator.Tests/XmlTests.cs +++ b/XmlSchemaClassGenerator.Tests/XmlTests.cs @@ -377,8 +377,32 @@ public void EditorBrowsableAttributeRespectsCodeTypeReferenceOptions(CodeTypeRef generatedType.First()); } + [Fact] + public void MixedTypeMustNotCollideWithExistingMembers() + { + const string xsd = @" + + + + + + +"; - [Theory] + var generatedType = ConvertXml(nameof(MixedTypeMustNotCollideWithExistingMembers), xsd, new Generator + { + NamespaceProvider = new NamespaceProvider + { + GenerateNamespace = key => "Test" + } + }); + + Assert.Contains( + @"public string[] Text_1 { get; set; }", + generatedType.First()); + } + + [Theory] [InlineData(@"xml/sameattributenames.xsd", @"xml/sameattributenames_import.xsd")] public void CollidingAttributeAndPropertyNamesCanBeResolved(params string[] files) { diff --git a/XmlSchemaClassGenerator/ModelBuilder.cs b/XmlSchemaClassGenerator/ModelBuilder.cs index b2184269..2afc7a68 100644 --- a/XmlSchemaClassGenerator/ModelBuilder.cs +++ b/XmlSchemaClassGenerator/ModelBuilder.cs @@ -53,7 +53,8 @@ public ModelBuilder(GeneratorConfiguration configuration, XmlSchemaSet set) foreach (var rootElement in set.GlobalElements.Values.Cast()) { - var source = new Uri(rootElement.GetSchema().SourceUri); + var rootSchema = rootElement.GetSchema(); + var source = !string.IsNullOrEmpty(rootSchema.SourceUri) ? new Uri(rootElement.GetSchema().SourceUri) : default(Uri); var qualifiedName = rootElement.ElementSchemaType.QualifiedName; if (qualifiedName.IsEmpty) { qualifiedName = rootElement.QualifiedName; } var type = CreateTypeModel(source, rootElement.ElementSchemaType, qualifiedName); diff --git a/XmlSchemaClassGenerator/TypeModel.cs b/XmlSchemaClassGenerator/TypeModel.cs index a65aab14..bcb3ec14 100644 --- a/XmlSchemaClassGenerator/TypeModel.cs +++ b/XmlSchemaClassGenerator/TypeModel.cs @@ -398,8 +398,15 @@ public override CodeTypeDeclaration Generate() } if (IsMixed && (BaseClass == null || (BaseClass is ClassModel && !AllBaseClasses.Any(b => b.IsMixed)))) - { - var text = new CodeMemberField(typeof(string), "Text"); + { + var propName = "Text"; + + // To not collide with any existing members + for (var propertyIndex = 1; Properties.Any(x => x.Name.Equals(propName, StringComparison.Ordinal)); propertyIndex++) + { + propName = $"Text_{propertyIndex}"; + } + var text = new CodeMemberField(typeof(string[]), propName); // hack to generate automatic property text.Name += " { get; set; }"; text.Attributes = MemberAttributes.Public;