Skip to content

Commit

Permalink
Merge pull request #181 from Etogy/master
Browse files Browse the repository at this point in the history
Add CLR type to the dictionary key for generated TypeModels
  • Loading branch information
mganss authored Apr 23, 2020
2 parents ab60544 + 2c012b5 commit 7b3bdc9
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 11 deletions.
35 changes: 35 additions & 0 deletions XmlSchemaClassGenerator.Tests/XmlTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,41 @@ public void CollidingAttributeAndPropertyNamesCanBeResolved(params string[] file
Assert.NotNull(assembly);
}

[Fact]
public void CollidingElementAndComplexTypeNamesCanBeResolved()
{
const string xsd = @"<?xml version=""1.0"" encoding = ""UTF-8""?>
<xs:schema elementFormDefault=""qualified"" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" targetNamespace=""http://local.none"">
<xs:complexType name=""MyType"">
<xs:sequence>
<xs:element maxOccurs=""1"" minOccurs=""0"" name=""output"" type=""xs:string""/>
</xs:sequence>
</xs:complexType>
<xs:element name=""MyType"">
<xs:simpleType>
<xs:restriction base=""xs:string"">
<xs:enumeration value=""Choice1""/>
<xs:enumeration value=""Choice2""/>
<xs:enumeration value=""Choice3""/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:schema>
";
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()
{
Expand Down
46 changes: 35 additions & 11 deletions XmlSchemaClassGenerator/ModelBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal class ModelBuilder
private readonly Dictionary<XmlQualifiedName, XmlSchemaAttributeGroup> AttributeGroups;
private readonly Dictionary<XmlQualifiedName, XmlSchemaGroup> Groups;
private readonly Dictionary<NamespaceKey, NamespaceModel> Namespaces = new Dictionary<NamespaceKey, NamespaceModel>();
private readonly Dictionary<XmlQualifiedName, TypeModel> Types = new Dictionary<XmlQualifiedName, TypeModel>();
private readonly Dictionary<string, TypeModel> Types = new Dictionary<string, TypeModel>();

private static readonly XmlQualifiedName AnyType = new XmlQualifiedName("anyType", XmlSchema.Namespace);

Expand All @@ -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<XmlSchema>().SelectMany(s => s.AttributeGroups.Values.Cast<XmlSchemaAttributeGroup>())
.DistinctBy(g => g.QualifiedName.ToString())
Expand Down Expand Up @@ -123,7 +124,8 @@ private void CreateElements(IEnumerable<XmlSchemaElement> 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);
Expand All @@ -132,7 +134,8 @@ private void CreateElements(IEnumerable<XmlSchemaElement> elements)
}
else
{
Types[rootElement.QualifiedName] = type;
var key = rootElement.GetType() + "#" + rootElement.QualifiedName;
Types[key] = type;
}
}
else
Expand All @@ -154,7 +157,8 @@ private void CreateElements(IEnumerable<XmlSchemaElement> 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;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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<XmlSchemaAttribute>());
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand All @@ -445,7 +469,7 @@ private IEnumerable<PropertyModel> 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;
Expand Down

0 comments on commit 7b3bdc9

Please sign in to comment.