diff --git a/XmlSchemaClassGenerator.Tests/XmlTests.cs b/XmlSchemaClassGenerator.Tests/XmlTests.cs index 8348d649..9099cdfb 100644 --- a/XmlSchemaClassGenerator.Tests/XmlTests.cs +++ b/XmlSchemaClassGenerator.Tests/XmlTests.cs @@ -689,6 +689,41 @@ public void CollidingAttributeAndPropertyNamesCanBeResolved(params string[] file Assert.NotNull(assembly); } + [Fact] + public void CollidingElementAndComplexTypeNamesCanBeResolved() + { + const string xsd = @" + + + + + + + + + + + + + + + + +"; + var generator = new Generator + { + NamespaceProvider = new NamespaceProvider + { + GenerateNamespace = key => "Test" + } + }; + + var generatedType = ConvertXml(nameof(CollidingElementAndComplexTypeNamesCanBeResolved), xsd, generator).First(); + + Assert.Contains(@"public partial class MyType", generatedType); + Assert.Contains(@"public enum MyType", generatedType); + } + [Fact] public void ComplexTypeWithAttributeGroupExtension() { diff --git a/XmlSchemaClassGenerator/ModelBuilder.cs b/XmlSchemaClassGenerator/ModelBuilder.cs index 5e54f86e..44da26d1 100644 --- a/XmlSchemaClassGenerator/ModelBuilder.cs +++ b/XmlSchemaClassGenerator/ModelBuilder.cs @@ -15,7 +15,7 @@ internal class ModelBuilder private readonly Dictionary AttributeGroups; private readonly Dictionary Groups; private readonly Dictionary Namespaces = new Dictionary(); - private readonly Dictionary Types = new Dictionary(); + private readonly Dictionary Types = new Dictionary(); private static readonly XmlQualifiedName AnyType = new XmlQualifiedName("anyType", XmlSchema.Namespace); @@ -35,7 +35,8 @@ public ModelBuilder(GeneratorConfiguration configuration, XmlSchemaSet set) UseDataTypeAttribute = false }; - Types[AnyType] = objectModel; + var key = typeof(XmlSchemaComplexType) + "#" + AnyType; + Types[key] = objectModel; AttributeGroups = set.Schemas().Cast().SelectMany(s => s.AttributeGroups.Values.Cast()) .DistinctBy(g => g.QualifiedName.ToString()) @@ -123,7 +124,8 @@ private void CreateElements(IEnumerable elements) derivedClassModel.Namespace.Types[derivedClassModel.Name] = derivedClassModel; } - Types[rootElement.QualifiedName] = derivedClassModel; + var key = rootElement.GetType() + "#" + rootElement.QualifiedName; + Types[key] = derivedClassModel; derivedClassModel.BaseClass = classModel; ((ClassModel)derivedClassModel.BaseClass).DerivedTypes.Add(derivedClassModel); @@ -132,7 +134,8 @@ private void CreateElements(IEnumerable elements) } else { - Types[rootElement.QualifiedName] = type; + var key = rootElement.GetType() + "#" + rootElement.QualifiedName; + Types[key] = type; } } else @@ -154,7 +157,8 @@ private void CreateElements(IEnumerable elements) private TypeModel CreateTypeModel(Uri source, XmlSchemaAnnotated type, XmlQualifiedName qualifiedName) { - if (!qualifiedName.IsEmpty && Types.TryGetValue(qualifiedName, out TypeModel typeModel)) + var key = type.GetType() + "#" + qualifiedName; + if (!qualifiedName.IsEmpty && Types.TryGetValue(key, out TypeModel typeModel)) { return typeModel; } @@ -197,7 +201,12 @@ private TypeModel CreateTypeModel(Uri source, XmlSchemaGroup group, NamespaceMod interfaceModel.Documentation.AddRange(docs); if (namespaceModel != null) { namespaceModel.Types[name] = interfaceModel; } - if (!qualifiedName.IsEmpty) { Types[qualifiedName] = interfaceModel; } + + if (!qualifiedName.IsEmpty) + { + var key = group.GetType() + "#" + qualifiedName; + Types[key] = interfaceModel; + } var particle = group.Particle; var items = GetElements(particle); @@ -225,7 +234,12 @@ private TypeModel CreateTypeModel(Uri source, XmlSchemaAttributeGroup attributeG interfaceModel.Documentation.AddRange(docs); if (namespaceModel != null) { namespaceModel.Types[name] = interfaceModel; } - if (!qualifiedName.IsEmpty) { Types[qualifiedName] = interfaceModel; } + + if (!qualifiedName.IsEmpty) + { + var key = attributeGroup.GetType() + "#" + qualifiedName; + Types[key] = interfaceModel; + } var items = attributeGroup.Attributes; var properties = CreatePropertiesForAttributes(source, interfaceModel, items.OfType()); @@ -264,7 +278,11 @@ private TypeModel CreateTypeModel(Uri source, XmlSchemaComplexType complexType, namespaceModel.Types[classModel.Name] = classModel; } - if (!qualifiedName.IsEmpty) { Types[qualifiedName] = classModel; } + if (!qualifiedName.IsEmpty) + { + var key = complexType.GetType() + "#" + qualifiedName; + Types[key] = classModel; + } if (complexType.BaseXmlSchemaType != null && complexType.BaseXmlSchemaType.QualifiedName != AnyType) { @@ -369,6 +387,7 @@ private TypeModel CreateTypeModel(XmlSchemaSimpleType simpleType, NamespaceModel Namespace = namespaceModel, XmlSchemaName = qualifiedName, XmlSchemaType = simpleType, + IsAnonymous = string.IsNullOrEmpty(simpleType.QualifiedName.Name), }; enumModel.Documentation.AddRange(docs); @@ -398,7 +417,8 @@ private TypeModel CreateTypeModel(XmlSchemaSimpleType simpleType, NamespaceModel if (!qualifiedName.IsEmpty) { - Types[qualifiedName] = enumModel; + var key = simpleType.GetType() + "#" + qualifiedName; + Types[key] = enumModel; } return enumModel; @@ -427,7 +447,11 @@ private TypeModel CreateTypeModel(XmlSchemaSimpleType simpleType, NamespaceModel namespaceModel.Types[simpleModel.Name] = simpleModel; } - if (!qualifiedName.IsEmpty) { Types[qualifiedName] = simpleModel; } + if (!qualifiedName.IsEmpty) + { + var key = simpleType.GetType() + "#" + qualifiedName; + Types[key] = simpleModel; + } return simpleModel; } @@ -445,7 +469,7 @@ private IEnumerable CreatePropertiesForAttributes(Uri source, Typ var attributeQualifiedName = attribute.AttributeSchemaType.QualifiedName; var attributeName = _configuration.NamingProvider.AttributeNameFromQualifiedName(attribute.QualifiedName); - if (attribute.Parent is XmlSchemaAttributeGroup attributeGroup && attributeGroup.QualifiedName != typeModel.XmlSchemaName && Types.TryGetValue(attributeGroup.QualifiedName, out var typeModelValue) && typeModelValue is InterfaceModel interfaceTypeModel) + if (attribute.Parent is XmlSchemaAttributeGroup attributeGroup && attributeGroup.QualifiedName != typeModel.XmlSchemaName && Types.TryGetValue(attributeGroup.GetType() + "#" + attributeGroup.QualifiedName, out var typeModelValue) && typeModelValue is InterfaceModel interfaceTypeModel) { var interfaceProperty = interfaceTypeModel.Properties.Single(p => p.XmlSchemaName == attribute.QualifiedName); attributeQualifiedName = interfaceProperty.Type.XmlSchemaName;