Skip to content

Commit

Permalink
Create individual classes for all root elements that derive from the …
Browse files Browse the repository at this point in the history
…same type (see #273)
  • Loading branch information
Michael Ganss committed Aug 5, 2021
1 parent 0b5f3fa commit 32dfff1
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 2 deletions.
48 changes: 46 additions & 2 deletions XmlSchemaClassGenerator/ModelBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ private void CreateSubstitutes()

private void AddXmlRootAttributeToAmbiguousTypes()
{
var ambiguousTypes = Types.Values.Where(t=>t.RootElementName == null && !(t is InterfaceModel)).GroupBy(t => t.Name);
var ambiguousTypes = Types.Values.Where(t => t.RootElementName == null && !t.IsAbstractRoot && !(t is InterfaceModel)).GroupBy(t => t.Name);
foreach (var ambiguousTypeGroup in ambiguousTypes)
{
var types = ambiguousTypeGroup.ToList();
Expand Down Expand Up @@ -253,7 +253,7 @@ private void CreateElements(IEnumerable<XmlSchemaElement> elements)
var type = CreateTypeModel(typeSource, rootElement.ElementSchemaType, qualifiedName);
ClassModel derivedClassModel = null;

if (type.RootElementName != null)
if (type.RootElementName != null || type.IsAbstractRoot)
{
if (type is ClassModel classModel)
{
Expand Down Expand Up @@ -283,6 +283,49 @@ private void CreateElements(IEnumerable<XmlSchemaElement> elements)
((ClassModel)derivedClassModel.BaseClass).DerivedTypes.Add(derivedClassModel);

derivedClassModel.RootElementName = rootElement.QualifiedName;

if (!type.IsAbstractRoot)
{
// Also create an empty derived class for the original root element

var originalClassModel = new ClassModel(_configuration)
{
Name = _configuration.NamingProvider.RootClassNameFromQualifiedName(type.RootElementName),
Namespace = classModel.Namespace
};

originalClassModel.Documentation.AddRange(classModel.Documentation);
classModel.Documentation.Clear();

if (originalClassModel.Namespace != null)
{
originalClassModel.Name = originalClassModel.Namespace.GetUniqueTypeName(originalClassModel.Name);
originalClassModel.Namespace.Types[originalClassModel.Name] = originalClassModel;
}

if (classModel.XmlSchemaName != null && !classModel.XmlSchemaName.IsEmpty)
{
key = BuildKey(classModel.RootElement, classModel.XmlSchemaName);
Types[key] = originalClassModel;
}

originalClassModel.BaseClass = classModel;
((ClassModel)originalClassModel.BaseClass).DerivedTypes.Add(originalClassModel);

originalClassModel.RootElementName = type.RootElementName;

if (classModel.RootElement.SubstitutionGroup != null
&& SubstitutionGroups.TryGetValue(classModel.RootElement.SubstitutionGroup, out var substitutes))
{
foreach (var substitute in substitutes.Where(s => s.Element == classModel.RootElement))
{
substitute.Type = originalClassModel;
}
}

classModel.RootElementName = null;
classModel.IsAbstractRoot = true;
}
}
else
{
Expand All @@ -297,6 +340,7 @@ private void CreateElements(IEnumerable<XmlSchemaElement> elements)
classModel.Documentation.AddRange(GetDocumentation(rootElement));
}

type.RootElement = rootElement;
type.RootElementName = rootElement.QualifiedName;
}

Expand Down
2 changes: 2 additions & 0 deletions XmlSchemaClassGenerator/TypeModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,9 @@ public abstract class TypeModel
protected static readonly CodeDomProvider CSharpProvider = CodeDomProvider.CreateProvider("CSharp");

public NamespaceModel Namespace { get; set; }
public XmlSchemaElement RootElement { get; set; }
public XmlQualifiedName RootElementName { get; set; }
public bool IsAbstractRoot { get; set; }
public string Name { get; set; }
public XmlQualifiedName XmlSchemaName { get; set; }
public XmlSchemaType XmlSchemaType { get; set; }
Expand Down

0 comments on commit 32dfff1

Please sign in to comment.