diff --git a/XmlSampleGenerator/XmlSampleGenerator.csproj b/XmlSampleGenerator/XmlSampleGenerator.csproj index 1ad5fe1e..325c420e 100644 --- a/XmlSampleGenerator/XmlSampleGenerator.csproj +++ b/XmlSampleGenerator/XmlSampleGenerator.csproj @@ -16,5 +16,7 @@ true false + False + False \ No newline at end of file diff --git a/XmlSchemaClassGenerator.Tests/DateTimeTypeTests.cs b/XmlSchemaClassGenerator.Tests/DateTimeTypeTests.cs index 5cd62ce5..7e98bbf7 100644 --- a/XmlSchemaClassGenerator.Tests/DateTimeTypeTests.cs +++ b/XmlSchemaClassGenerator.Tests/DateTimeTypeTests.cs @@ -103,6 +103,34 @@ public void WhenDateTimeOffsetIsNotUsed_DataTypePropertyIsPresent() Assert.Contains(expectedXmlSerializationAttribute, generatedProperty); } + [Fact] + public void WhenDateTimeOffsetIsNotUsed_DataTypePropertyIsPresent2() + { + var xsd = @$" + + + + + + +"; + + var generatedType = ConvertXml( + xsd, new() + { + NamespaceProvider = new() + { + GenerateNamespace = _ => "Test" + }, + DateTimeWithTimeZone = true + }); + + var expectedXmlSerializationAttribute = "[System.Xml.Serialization.XmlElementAttribute(\"someDate\", DataType=\"date\")]"; + var generatedProperty = generatedType.First(); + + Assert.Contains(expectedXmlSerializationAttribute, generatedProperty); + } + [Theory] [InlineData(false, "System.DateTime")] [InlineData(true, "System.DateTimeOffset")] diff --git a/XmlSchemaClassGenerator/CodeUtilities.cs b/XmlSchemaClassGenerator/CodeUtilities.cs index 8c61b1f7..1819522e 100644 --- a/XmlSchemaClassGenerator/CodeUtilities.cs +++ b/XmlSchemaClassGenerator/CodeUtilities.cs @@ -67,10 +67,11 @@ public static string ToCamelCase(this string s) => string.IsNullOrEmpty(s) ? s public static string ToBackingField(this string propertyName, string privateFieldPrefix) => string.Concat(privateFieldPrefix, propertyName.ToCamelCase()); - public static bool? IsDataTypeAttributeAllowed(this XmlSchemaDatatype type) => type.TypeCode switch + public static bool? IsDataTypeAttributeAllowed(this XmlSchemaDatatype type, GeneratorConfiguration configuration) => type.TypeCode switch { XmlTypeCode.AnyAtomicType => false,// union - XmlTypeCode.DateTime or XmlTypeCode.Time or XmlTypeCode.Date or XmlTypeCode.Base64Binary or XmlTypeCode.HexBinary => true, + XmlTypeCode.DateTime or XmlTypeCode.Time => !configuration.DateTimeWithTimeZone, + XmlTypeCode.Date or XmlTypeCode.Base64Binary or XmlTypeCode.HexBinary => true, _ => false, }; diff --git a/XmlSchemaClassGenerator/ModelBuilder.cs b/XmlSchemaClassGenerator/ModelBuilder.cs index 6a49bf52..af223bf0 100644 --- a/XmlSchemaClassGenerator/ModelBuilder.cs +++ b/XmlSchemaClassGenerator/ModelBuilder.cs @@ -16,11 +16,11 @@ internal class ModelBuilder private const string ElementName = "Element"; private readonly GeneratorConfiguration _configuration; private readonly XmlSchemaSet _set; - private readonly Dictionary> AttributeGroups = new(); - private readonly Dictionary> Groups = new(); - private readonly Dictionary Namespaces = new(); - private readonly Dictionary Types = new(); - private readonly Dictionary> SubstitutionGroups = new(); + private readonly Dictionary> AttributeGroups = []; + private readonly Dictionary> Groups = []; + private readonly Dictionary Namespaces = []; + private readonly Dictionary Types = []; + private readonly Dictionary> SubstitutionGroups = []; private static readonly XmlQualifiedName AnyType = new("anyType", XmlSchema.Namespace); @@ -62,7 +62,7 @@ public ModelBuilder(GeneratorConfiguration configuration, XmlSchemaSet set) { if (!AttributeGroups.ContainsKey(currentAttributeGroup.QualifiedName)) { - AttributeGroups.Add(currentAttributeGroup.QualifiedName, new HashSet()); + AttributeGroups.Add(currentAttributeGroup.QualifiedName, []); } AttributeGroups[currentAttributeGroup.QualifiedName].Add(currentAttributeGroup); @@ -75,7 +75,7 @@ public ModelBuilder(GeneratorConfiguration configuration, XmlSchemaSet set) { if (!Groups.ContainsKey(currentSchemaGroup.QualifiedName)) { - Groups.Add(currentSchemaGroup.QualifiedName, new HashSet()); + Groups.Add(currentSchemaGroup.QualifiedName, []); } Groups[currentSchemaGroup.QualifiedName].Add(currentSchemaGroup); @@ -314,7 +314,7 @@ private void CreateElement(XmlSchemaElement rootElement) { if (!SubstitutionGroups.TryGetValue(rootElement.SubstitutionGroup, out var substitutes)) { - substitutes = new HashSet(); + substitutes = []; SubstitutionGroups.Add(rootElement.SubstitutionGroup, substitutes); } @@ -422,24 +422,14 @@ private TypeModel CreateTypeModel(XmlQualifiedName qualifiedName, XmlSchemaAnnot return typeModelBuilder.Create(type); } - private sealed class TypeModelBuilder + private sealed class TypeModelBuilder(ModelBuilder builder, GeneratorConfiguration configuration, XmlQualifiedName qualifiedName, NamespaceModel namespaceModel, List docs, Uri source) { - private readonly ModelBuilder builder; - private readonly GeneratorConfiguration _configuration; - private readonly XmlQualifiedName qualifiedName; - private readonly NamespaceModel namespaceModel; - private readonly List docs; - private readonly Uri source; - - public TypeModelBuilder(ModelBuilder builder, GeneratorConfiguration configuration, XmlQualifiedName qualifiedName, NamespaceModel namespaceModel, List docs, Uri source) - { - this.builder = builder; - _configuration = configuration; - this.qualifiedName = qualifiedName; - this.namespaceModel = namespaceModel; - this.docs = docs; - this.source = source; - } + private readonly ModelBuilder builder = builder; + private readonly GeneratorConfiguration _configuration = configuration; + private readonly XmlQualifiedName qualifiedName = qualifiedName; + private readonly NamespaceModel namespaceModel = namespaceModel; + private readonly List docs = docs; + private readonly Uri source = source; internal TypeModel Create(XmlSchemaAnnotated type) => type switch { @@ -661,7 +651,7 @@ XmlSchemaSimpleTypeUnion typeUnion when AllMembersHaveFacets(typeUnion, out base restrictions = CodeUtilities.GetRestrictions(facets, simpleType, _configuration).Where(r => r != null).Sanitize().ToList(); } - return CreateSimpleModel(simpleType, restrictions ?? new()); + return CreateSimpleModel(simpleType, restrictions ?? []); static bool AllMembersHaveFacets(XmlSchemaSimpleTypeUnion typeUnion, out List> baseFacets) { @@ -673,7 +663,7 @@ static bool AllMembersHaveFacets(XmlSchemaSimpleTypeUnion typeUnion, out List MergeRestrictions(XmlSchemaSimpleType type) { - if (type == null) return new(); + if (type == null) return []; var baseFacets = MergeRestrictions(type.BaseXmlSchemaType as XmlSchemaSimpleType); if (type.Content is XmlSchemaSimpleTypeRestriction typeRestriction) { @@ -908,7 +898,7 @@ private IEnumerable CreatePropertiesForElements(Uri source, TypeM { // ElementSchemaType must be non-null. This is not the case when maxOccurs="0". case XmlSchemaElement element when element.ElementSchemaType != null: - property = PropertyFromElement(owningTypeModel, element, particle, item, substitute, passProperties ? properties : new List()); + property = PropertyFromElement(owningTypeModel, element, particle, item, substitute, passProperties ? properties : []); break; case XmlSchemaAny: SimpleModel typeModel = new(_configuration) @@ -1093,7 +1083,7 @@ public IEnumerable GetElements(XmlSchemaObject item, XmlSchemaObject p public static List GetDocumentation(XmlSchemaAnnotated annotated) { - return annotated.Annotation == null ? new List() + return annotated.Annotation == null ? [] : annotated.Annotation.Items.OfType() .Where(d => d.Markup?.Length > 0) .Select(d => d.Markup.Select(m => new DocumentationModel { Language = d.Language, Text = m.OuterXml })) diff --git a/XmlSchemaClassGenerator/TypeModel.cs b/XmlSchemaClassGenerator/TypeModel.cs index be85c746..5684968c 100644 --- a/XmlSchemaClassGenerator/TypeModel.cs +++ b/XmlSchemaClassGenerator/TypeModel.cs @@ -326,7 +326,7 @@ public override CodeTypeDeclaration Generate() docs.AddRange(simpleModel.Restrictions.Select(r => new DocumentationModel { Language = English, Text = r.Description })); text.CustomAttributes.AddRange(simpleModel.GetRestrictionAttributes().ToArray()); - if (BaseClass.GetQualifiedName() is { Namespace: XmlSchema.Namespace, Name: var name } && (simpleModel.XmlSchemaType.Datatype.IsDataTypeAttributeAllowed() ?? simpleModel.UseDataTypeAttribute)) + if (BaseClass.GetQualifiedName() is { Namespace: XmlSchema.Namespace, Name: var name } && (simpleModel.XmlSchemaType.Datatype.IsDataTypeAttributeAllowed(Configuration) ?? simpleModel.UseDataTypeAttribute)) attribute.Arguments.Add(new CodeAttributeArgument(nameof(XmlTextAttribute.DataType), new CodePrimitiveExpression(name))); } @@ -1104,8 +1104,7 @@ private IEnumerable GetAttributes(bool isArray, TypeMo { var qualifiedName = xmlSchemaType.GetQualifiedName(); - if (qualifiedName.Namespace == XmlSchema.Namespace && qualifiedName.Name != "anySimpleType" && - !(xmlSchemaType.Datatype.ValueType == typeof(DateTime) && Configuration.DateTimeWithTimeZone)) + if (qualifiedName.Namespace == XmlSchema.Namespace && qualifiedName.Name != "anySimpleType") { args.Add(new("DataType", new CodePrimitiveExpression(qualifiedName.Name))); break; @@ -1250,7 +1249,7 @@ public override CodeTypeReference GetReferenceFor(NamespaceModel referencingName // XmlSerializer is inconsistent: maps xs:decimal to decimal but xs:integer to string, // even though xs:integer is a restriction of xs:decimal type = XmlSchemaType.Datatype.GetEffectiveType(Configuration, Restrictions, XmlSchemaType, attribute); - UseDataTypeAttribute = XmlSchemaType.Datatype.IsDataTypeAttributeAllowed() ?? UseDataTypeAttribute; + UseDataTypeAttribute = XmlSchemaType.Datatype.IsDataTypeAttributeAllowed(Configuration) ?? UseDataTypeAttribute; } if (collection)