diff --git a/XmlSchemaClassGenerator.Tests/AssertEx.cs b/XmlSchemaClassGenerator.Tests/AssertEx.cs
index b1ba7b28..73d418ad 100644
--- a/XmlSchemaClassGenerator.Tests/AssertEx.cs
+++ b/XmlSchemaClassGenerator.Tests/AssertEx.cs
@@ -71,7 +71,7 @@ public static void Equal(object o1, object o2)
}
else
{
- foreach (var prop in type1.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.CanRead))
+ foreach (var prop in type1.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.CanRead && !p.GetIndexParameters().Any()))
{
var val1 = prop.GetValue(o1);
var val2 = prop.GetValue(o2);
diff --git a/XmlSchemaClassGenerator.Tests/XmlSchemaClassGenerator.Tests.csproj b/XmlSchemaClassGenerator.Tests/XmlSchemaClassGenerator.Tests.csproj
index b3b74da9..8b6956fc 100644
--- a/XmlSchemaClassGenerator.Tests/XmlSchemaClassGenerator.Tests.csproj
+++ b/XmlSchemaClassGenerator.Tests/XmlSchemaClassGenerator.Tests.csproj
@@ -226,6 +226,10 @@
Designer
PreserveNewest
+
+ Designer
+ PreserveNewest
+
Designer
PreserveNewest
diff --git a/XmlSchemaClassGenerator.Tests/XmlTests.cs b/XmlSchemaClassGenerator.Tests/XmlTests.cs
index c36c0c9e..0e412c09 100644
--- a/XmlSchemaClassGenerator.Tests/XmlTests.cs
+++ b/XmlSchemaClassGenerator.Tests/XmlTests.cs
@@ -136,7 +136,7 @@ private void DeserializeSampleXml(string pattern, Assembly assembly)
set.Compile();
- foreach (var rootElement in set.GlobalElements.Values.Cast())
+ foreach (var rootElement in set.GlobalElements.Values.Cast().Where(e => !e.IsAbstract))
{
var type = FindType(assembly, rootElement.QualifiedName);
var serializer = new XmlSerializer(type);
diff --git a/XmlSchemaClassGenerator.Tests/xsd/is24immotransfer/is24immotransfer.xsd b/XmlSchemaClassGenerator.Tests/xsd/is24immotransfer/is24immotransfer.xsd
index 31fa6380..03e29f98 100644
--- a/XmlSchemaClassGenerator.Tests/xsd/is24immotransfer/is24immotransfer.xsd
+++ b/XmlSchemaClassGenerator.Tests/xsd/is24immotransfer/is24immotransfer.xsd
@@ -134,8 +134,8 @@
- Freitext, maximal 2000 Zeichen.
- Zur Formatierung wird als HTML-Tag nur 'BR' unterstuetzt.
+ Freitext, maximal 2000 Zeichen.
+ Zur Formatierung wird als HTML-Tag nur 'BR' unterstuetzt.
CDATA-Abschnitte werden nicht unterstuetzt.
@@ -195,7 +195,7 @@
-
+
positive natuerliche Zahl, zweistellig
@@ -213,7 +213,7 @@
-
+
positive natuerliche Zahl, dreistellig
@@ -1802,7 +1802,7 @@
- entspricht 'ja'
+ entspricht 'ja'
(aus Kompatibilitaetsgruenden, wird in zukuenftigen Versionen nicht mehr unterstuetzt)
@@ -1810,7 +1810,7 @@
- entspricht 'nein'
+ entspricht 'nein'
(aus Kompatibilitaetsgruenden, wird in zukuenftigen Versionen nicht mehr unterstuetzt)
@@ -1921,7 +1921,7 @@
-
+
@@ -2150,7 +2150,7 @@
- aus Kompatibilitaetsgruenden weiter vorhanden: Benutze stattdessen 'Reihenmittelhaus' oder 'Reiheneckhaus'
+ aus Kompatibilitaetsgruenden weiter vorhanden: Benutze stattdessen 'Reihenmittelhaus' oder 'Reiheneckhaus'
(wird in zukuenftigen Versionen nicht mehr unterstuetzt)
@@ -2158,7 +2158,7 @@
- aus Kompatibilitaetsgruenden weiter vorhanden: Benutze stattdessen 'Mehrfamilienhaus'
+ aus Kompatibilitaetsgruenden weiter vorhanden: Benutze stattdessen 'Mehrfamilienhaus'
(wird in zukuenftigen Versionen nicht mehr unterstuetzt)
@@ -2203,7 +2203,7 @@
- Alle Nutzungsarten (Objektkategorie 2) fuer Grundstuecke
+ Alle Nutzungsarten (Objektkategorie 2) fuer Grundstuecke
des alten allgemeinen Grundstueckstyps
@@ -2399,7 +2399,7 @@
- Garagen/Stellplatz-Kategorien fuer Garagen/Stellplaetze von Hauser-, Wohnungs- und
+ Garagen/Stellplatz-Kategorien fuer Garagen/Stellplaetze von Hauser-, Wohnungs- und
WAZ-Typen
@@ -2516,10 +2516,8 @@
-
-
-
-
+
+
@@ -2552,14 +2550,14 @@
Zusaetzliche Angabe der Heizkosten / Warmwasser, monatlich.
- Wenn Sie die Heizkosten angeben, dann geben Sie bitte auch an, ob diese in den Nebenkosten enthalten sind.
+ Wenn Sie die Heizkosten angeben, dann geben Sie bitte auch an, ob diese in den Nebenkosten enthalten sind.
- Das Attribut besagt, ob die Nebenkosten die Heizkosten enthalten.
+ Das Attribut besagt, ob die Nebenkosten die Heizkosten enthalten.
Wenn Sie die Heizkosten angeben, dann geben Sie bitte auch an, ob diese in den Nebenkosten enthalten sind.
@@ -2575,18 +2573,18 @@
-
+
-
+
-
+
-
+
@@ -2594,13 +2592,13 @@
-
+
-
+
-
+
@@ -2610,10 +2608,10 @@
-
+
-
+
@@ -2623,10 +2621,10 @@
-
+
-
+
@@ -2634,14 +2632,14 @@
-
+
-
+
@@ -2657,7 +2655,7 @@
-
+
@@ -2759,22 +2757,8 @@
Empfohlene Nutzungen fuer Grundstuecke/Wohnen
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -2782,31 +2766,8 @@
Empfohlene Nutzungen fuer Grundstuecke/Gewerbe
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -2979,7 +2940,7 @@
- aus Kompatibilitaetsgruenden nur als 'optional' deklariert:
+ aus Kompatibilitaetsgruenden nur als 'optional' deklariert:
Der Wert sollte aber angegeben werden.
@@ -3280,42 +3241,14 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -3324,113 +3257,32 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- entspricht: Seniorengerechtes Wohnen
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -3499,34 +3351,8 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Provisionstext, -hinweis und -pflichtig-Flag werden fuer Typenhaeuser nicht unterstuetzt
-
-
-
-
- Provisionstext, -hinweis und -pflichtig-Flag werden fuer Typenhaeuser nicht unterstuetzt
-
-
-
+
+
@@ -3547,23 +3373,8 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -3584,24 +3395,8 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -3673,7 +3468,7 @@
-
+
@@ -3692,11 +3487,11 @@
-
+
-
+
diff --git a/XmlSchemaClassGenerator/Generator.cs b/XmlSchemaClassGenerator/Generator.cs
index 0b2db114..6e5dcdb3 100644
--- a/XmlSchemaClassGenerator/Generator.cs
+++ b/XmlSchemaClassGenerator/Generator.cs
@@ -479,6 +479,7 @@ private TypeModel CreateTypeModel(Uri source, XmlSchemaAnnotated type, XmlQualif
IsAbstract = complexType.IsAbstract,
IsAnonymous = complexType.QualifiedName.Name == "",
IsMixed = complexType.IsMixed,
+ IsSubstitution = complexType.Parent is XmlSchemaElement && !((XmlSchemaElement)complexType.Parent).SubstitutionGroup.IsEmpty,
EnableDataBinding = EnableDataBinding,
};
diff --git a/XmlSchemaClassGenerator/TypeModel.cs b/XmlSchemaClassGenerator/TypeModel.cs
index 222cfa91..33b449d0 100644
--- a/XmlSchemaClassGenerator/TypeModel.cs
+++ b/XmlSchemaClassGenerator/TypeModel.cs
@@ -193,6 +193,7 @@ public class ClassModel : TypeModel
{
public bool IsAbstract { get; set; }
public bool IsMixed { get; set; }
+ public bool IsSubstitution { get; set; }
public TypeModel BaseClass { get; set; }
public List Properties { get; set; }
public List Interfaces { get; set; }
@@ -781,8 +782,8 @@ public void AddMembersTo(CodeTypeDeclaration typeDeclaration, bool withDataBindi
typeDeclaration.Members.Add(specifiedProperty);
}
- var attribute = GetAttribute(isArray);
- member.CustomAttributes.Add(attribute);
+ var attributes = GetAttributes(isArray).ToArray();
+ member.CustomAttributes.AddRange(attributes);
// initialize List<>
if (IsCollection || isArray)
@@ -806,11 +807,14 @@ public void AddMembersTo(CodeTypeDeclaration typeDeclaration, bool withDataBindi
if (isArray)
{
var arrayItemProperty = typeClassModel.Properties[0];
- var propertyAttribute = arrayItemProperty.GetAttribute(false);
+ var propertyAttributes = arrayItemProperty.GetAttributes(false).ToList();
// HACK: repackage as ArrayItemAttribute
- var arrayItemAttribute = new CodeAttributeDeclaration(new CodeTypeReference(typeof(XmlArrayItemAttribute)),
- propertyAttribute.Arguments.Cast().Where(x => !string.Equals(x.Name, "Order", StringComparison.Ordinal)).ToArray());
- member.CustomAttributes.Add(arrayItemAttribute);
+ foreach (var propertyAttribute in propertyAttributes)
+ {
+ var arrayItemAttribute = new CodeAttributeDeclaration(new CodeTypeReference(typeof(XmlArrayItemAttribute)),
+ propertyAttribute.Arguments.Cast().Where(x => !string.Equals(x.Name, "Order", StringComparison.Ordinal)).ToArray());
+ member.CustomAttributes.Add(arrayItemAttribute);
+ }
}
if (IsKey)
@@ -825,79 +829,99 @@ public void AddMembersTo(CodeTypeDeclaration typeDeclaration, bool withDataBindi
}
}
- private CodeAttributeDeclaration GetAttribute(bool isArray)
+ private IEnumerable GetAttributes(bool isArray)
{
- CodeAttributeDeclaration attribute;
+ var attributes = new List();
if (IsKey && XmlSchemaName == null)
{
- attribute = new CodeAttributeDeclaration(new CodeTypeReference(typeof(XmlIgnoreAttribute)));
- return attribute;
+ attributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(XmlIgnoreAttribute))));
+ return attributes;
}
if (IsAttribute)
{
if (IsAny)
{
- attribute = new CodeAttributeDeclaration(new CodeTypeReference(typeof(XmlAnyAttributeAttribute)));
+ attributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(XmlAnyAttributeAttribute))));
}
else
{
- attribute = new CodeAttributeDeclaration(new CodeTypeReference(typeof(XmlAttributeAttribute)),
- new CodeAttributeArgument(new CodePrimitiveExpression(XmlSchemaName.Name)));
+ attributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(XmlAttributeAttribute)),
+ new CodeAttributeArgument(new CodePrimitiveExpression(XmlSchemaName.Name))));
}
}
else if (!isArray)
{
if (IsAny)
{
- attribute = new CodeAttributeDeclaration(new CodeTypeReference(typeof(XmlAnyElementAttribute)));
+ attributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(XmlAnyElementAttribute))));
}
else
{
- attribute = new CodeAttributeDeclaration(new CodeTypeReference(typeof(XmlElementAttribute)),
- new CodeAttributeArgument(new CodePrimitiveExpression(XmlSchemaName.Name)));
+ var classType = PropertyType as ClassModel;
+ if (classType != null && classType.IsAbstract && classType.DerivedTypes.Any())
+ {
+ var derivedTypes = classType.GetAllDerivedTypes().Where(t => t.IsSubstitution);
+ foreach (var derivedType in derivedTypes)
+ {
+ var derivedAttribute = new CodeAttributeDeclaration(new CodeTypeReference(typeof(XmlElementAttribute)),
+ new CodeAttributeArgument(new CodePrimitiveExpression(derivedType.XmlSchemaName.Name)),
+ new CodeAttributeArgument("Type", new CodeTypeOfExpression(derivedType.GetReferenceFor(OwningType.Namespace, false))));
+ if (Order != null)
+ derivedAttribute.Arguments.Add(new CodeAttributeArgument("Order",
+ new CodePrimitiveExpression(Order.Value)));
+ attributes.Add(derivedAttribute);
+ }
+ }
+
+ var attribute = new CodeAttributeDeclaration(new CodeTypeReference(typeof(XmlElementAttribute)),
+ new CodeAttributeArgument(new CodePrimitiveExpression(XmlSchemaName.Name)));
if (Order != null)
attribute.Arguments.Add(new CodeAttributeArgument("Order",
new CodePrimitiveExpression(Order.Value)));
+ attributes.Add(attribute);
}
}
else
{
- attribute = new CodeAttributeDeclaration(new CodeTypeReference(typeof(XmlArrayAttribute)),
- new CodeAttributeArgument(new CodePrimitiveExpression(XmlSchemaName.Name)));
+ attributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(XmlArrayAttribute)),
+ new CodeAttributeArgument(new CodePrimitiveExpression(XmlSchemaName.Name))));
}
- if (Form == XmlSchemaForm.Qualified)
- {
- attribute.Arguments.Add(new CodeAttributeArgument("Namespace", new CodePrimitiveExpression(OwningType.XmlSchemaName.Namespace)));
- }
- else if (XmlNamespace != null)
- {
- attribute.Arguments.Add(new CodeAttributeArgument("Namespace", new CodePrimitiveExpression(XmlNamespace)));
- }
- else if (!IsAny)
+ foreach (var attribute in attributes)
{
- attribute.Arguments.Add(new CodeAttributeArgument("Form",
- new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(new CodeTypeReference(typeof(XmlSchemaForm))),
- "Unqualified")));
- }
+ if (Form == XmlSchemaForm.Qualified)
+ {
+ attribute.Arguments.Add(new CodeAttributeArgument("Namespace", new CodePrimitiveExpression(OwningType.XmlSchemaName.Namespace)));
+ }
+ else if (XmlNamespace != null)
+ {
+ attribute.Arguments.Add(new CodeAttributeArgument("Namespace", new CodePrimitiveExpression(XmlNamespace)));
+ }
+ else if (!IsAny)
+ {
+ attribute.Arguments.Add(new CodeAttributeArgument("Form",
+ new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(new CodeTypeReference(typeof(XmlSchemaForm))),
+ "Unqualified")));
+ }
- if (IsNillable)
- attribute.Arguments.Add(new CodeAttributeArgument("IsNullable", new CodePrimitiveExpression(true)));
+ if (IsNillable)
+ attribute.Arguments.Add(new CodeAttributeArgument("IsNullable", new CodePrimitiveExpression(true)));
- var simpleModel = Type as SimpleModel;
- if (simpleModel != null && simpleModel.UseDataTypeAttribute)
- {
- var name = Type.XmlSchemaType.GetQualifiedName();
- if (name.Namespace == XmlSchema.Namespace)
+ var simpleModel = Type as SimpleModel;
+ if (simpleModel != null && simpleModel.UseDataTypeAttribute)
{
- var dataType = new CodeAttributeArgument("DataType", new CodePrimitiveExpression(name.Name));
- attribute.Arguments.Add(dataType);
+ var name = Type.XmlSchemaType.GetQualifiedName();
+ if (name.Namespace == XmlSchema.Namespace)
+ {
+ var dataType = new CodeAttributeArgument("DataType", new CodePrimitiveExpression(name.Name));
+ attribute.Arguments.Add(dataType);
+ }
}
}
- return attribute;
+ return attributes;
}
}