Skip to content

Commit 32dfff1

Browse files
author
Michael Ganss
committed
Create individual classes for all root elements that derive from the same type (see #273)
1 parent 0b5f3fa commit 32dfff1

File tree

2 files changed

+48
-2
lines changed

2 files changed

+48
-2
lines changed

XmlSchemaClassGenerator/ModelBuilder.cs

+46-2
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ private void CreateSubstitutes()
137137

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

256-
if (type.RootElementName != null)
256+
if (type.RootElementName != null || type.IsAbstractRoot)
257257
{
258258
if (type is ClassModel classModel)
259259
{
@@ -283,6 +283,49 @@ private void CreateElements(IEnumerable<XmlSchemaElement> elements)
283283
((ClassModel)derivedClassModel.BaseClass).DerivedTypes.Add(derivedClassModel);
284284

285285
derivedClassModel.RootElementName = rootElement.QualifiedName;
286+
287+
if (!type.IsAbstractRoot)
288+
{
289+
// Also create an empty derived class for the original root element
290+
291+
var originalClassModel = new ClassModel(_configuration)
292+
{
293+
Name = _configuration.NamingProvider.RootClassNameFromQualifiedName(type.RootElementName),
294+
Namespace = classModel.Namespace
295+
};
296+
297+
originalClassModel.Documentation.AddRange(classModel.Documentation);
298+
classModel.Documentation.Clear();
299+
300+
if (originalClassModel.Namespace != null)
301+
{
302+
originalClassModel.Name = originalClassModel.Namespace.GetUniqueTypeName(originalClassModel.Name);
303+
originalClassModel.Namespace.Types[originalClassModel.Name] = originalClassModel;
304+
}
305+
306+
if (classModel.XmlSchemaName != null && !classModel.XmlSchemaName.IsEmpty)
307+
{
308+
key = BuildKey(classModel.RootElement, classModel.XmlSchemaName);
309+
Types[key] = originalClassModel;
310+
}
311+
312+
originalClassModel.BaseClass = classModel;
313+
((ClassModel)originalClassModel.BaseClass).DerivedTypes.Add(originalClassModel);
314+
315+
originalClassModel.RootElementName = type.RootElementName;
316+
317+
if (classModel.RootElement.SubstitutionGroup != null
318+
&& SubstitutionGroups.TryGetValue(classModel.RootElement.SubstitutionGroup, out var substitutes))
319+
{
320+
foreach (var substitute in substitutes.Where(s => s.Element == classModel.RootElement))
321+
{
322+
substitute.Type = originalClassModel;
323+
}
324+
}
325+
326+
classModel.RootElementName = null;
327+
classModel.IsAbstractRoot = true;
328+
}
286329
}
287330
else
288331
{
@@ -297,6 +340,7 @@ private void CreateElements(IEnumerable<XmlSchemaElement> elements)
297340
classModel.Documentation.AddRange(GetDocumentation(rootElement));
298341
}
299342

343+
type.RootElement = rootElement;
300344
type.RootElementName = rootElement.QualifiedName;
301345
}
302346

XmlSchemaClassGenerator/TypeModel.cs

+2
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,9 @@ public abstract class TypeModel
111111
protected static readonly CodeDomProvider CSharpProvider = CodeDomProvider.CreateProvider("CSharp");
112112

113113
public NamespaceModel Namespace { get; set; }
114+
public XmlSchemaElement RootElement { get; set; }
114115
public XmlQualifiedName RootElementName { get; set; }
116+
public bool IsAbstractRoot { get; set; }
115117
public string Name { get; set; }
116118
public XmlQualifiedName XmlSchemaName { get; set; }
117119
public XmlSchemaType XmlSchemaType { get; set; }

0 commit comments

Comments
 (0)