Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
daviddays committed Feb 20, 2019
2 parents 9e8c51b + f77c79a commit c19f626
Show file tree
Hide file tree
Showing 8 changed files with 158 additions and 13 deletions.
96 changes: 93 additions & 3 deletions XmlSchemaClassGenerator.Tests/XmlTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ private IEnumerable<string> ConvertXml(string name, string xsd, Generator genera
{
var schema = XmlSchema.Read(stringReader, (s, e) =>
{
throw new InvalidOperationException();
throw new InvalidOperationException($"{e.Severity}: {e.Message}",e.Exception);
});

set.Add(schema);
Expand Down Expand Up @@ -632,7 +632,7 @@ public void ChoiceMembersAreNullable()
}

[Fact]
public void AssemblyVisibleIsInternal()
public void AssemblyVisibleIsInternalClass()
{
// We test to see whether choices which are part of a larger ComplexType are marked as nullable.
// Because nullability isn't directly exposed in the generated C#, we use "XXXSpecified" on a value type
Expand Down Expand Up @@ -675,13 +675,103 @@ public void AssemblyVisibleIsInternal()
Assert.Contains("internal partial class Root", content);
}

[Fact]
public void AssemblyVisibleIsInternalEnum()
{
// We test to see whether choices which are part of a larger ComplexType are marked as nullable.
// Because nullability isn't directly exposed in the generated C#, we use "XXXSpecified" on a value type
// as a proxy.

const string xsd = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<xs:schema xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:xlink=""http://www.w3.org/1999/xlink"" elementFormDefault=""qualified"" attributeFormDefault=""unqualified"">
<xs:simpleType name=""Answer"">
<xs:restriction base=""xs:string"">
<xs:enumeration value=""Yes""/>
<xs:enumeration value=""No""/>
<xs:enumeration value=""Probably""/>
</xs:restriction>
</xs:simpleType>
</xs:schema>";

var generator = new Generator
{
NamespaceProvider = new NamespaceProvider
{
GenerateNamespace = key => "Test"
},
AssemblyVisible = true
};
var contents = ConvertXml(nameof(ComplexTypeWithAttributeGroupExtension), xsd, generator);
var content = Assert.Single(contents);

Assert.Contains("internal enum Answer", content);
}

[Fact]
public void AssemblyVisibleIsInternalInterface()
{
// We test to see whether choices which are part of a larger ComplexType are marked as nullable.
// Because nullability isn't directly exposed in the generated C#, we use "XXXSpecified" on a value type
// as a proxy.

const string xsd = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<xs:schema xmlns:tns=""http://test.test/schema/AssemblyVisibleIsInternalInterface"" targetNamespace=""http://test.test/schema/AssemblyVisibleIsInternalInterface"" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:xlink=""http://www.w3.org/1999/xlink"" elementFormDefault=""qualified"" attributeFormDefault=""unqualified"">
<xs:complexType name=""NamedType"">
<xs:attributeGroup ref=""tns:NamedElement""/>
</xs:complexType>
<xs:attributeGroup name=""NamedElement"">
<xs:attribute name=""Name"" use=""required"" type=""xs:string"" />
</xs:attributeGroup>
</xs:schema>";

var generator = new Generator
{
NamespaceProvider = new NamespaceProvider
{
GenerateNamespace = key => "Test"
},
GenerateInterfaces = true,
AssemblyVisible = true
};
var contents = ConvertXml(nameof(ComplexTypeWithAttributeGroupExtension), xsd, generator);
var content = Assert.Single(contents);

Assert.Contains("internal partial interface INamedElement", content);
}

[Fact]
public void DecimalSeparatorTest()
{
// see https://github.com/mganss/XmlSchemaClassGenerator/issues/101

const string xsd = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<xs:schema xmlns:xs=""http://www.w3.org/2001/XMLSchema"" elementFormDefault=""qualified"" attributeFormDefault=""unqualified"">
<xs:complexType name=""NamedType"">
<xs:attribute name=""SomeAttr"" type=""xs:decimal"" default=""1.5"" />
</xs:complexType>
</xs:schema>";

var generator = new Generator
{
NamespaceProvider = new NamespaceProvider
{
GenerateNamespace = key => "Test",
},
GenerateInterfaces = true,
AssemblyVisible = true
};
var contents = ConvertXml(nameof(ComplexTypeWithAttributeGroupExtension), xsd, generator);
var content = Assert.Single(contents);

Assert.Contains("private decimal _someAttr = 1.5m;", content);
}

private static void CompareOutput(string expected, string actual)
{
string Normalize(string input) => Regex.Replace(input, @"[ \t]*\r\n", "\n");
Assert.Equal(Normalize(expected), Normalize(actual));
}


[Theory]
[InlineData(typeof(decimal), "decimal")]
[InlineData(typeof(long), "long")]
Expand Down
6 changes: 6 additions & 0 deletions XmlSchemaClassGenerator.sln
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
README.md = README.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "xscgen-proj", "xscgen-proj\xscgen-proj.csproj", "{2F20FF02-12AB-448B-BC78-DD76DD4C9E66}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -44,6 +46,10 @@ Global
{C5C1FF7F-31AD-4D4F-81F3-C9F54516D9D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C5C1FF7F-31AD-4D4F-81F3-C9F54516D9D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C5C1FF7F-31AD-4D4F-81F3-C9F54516D9D0}.Release|Any CPU.Build.0 = Release|Any CPU
{2F20FF02-12AB-448B-BC78-DD76DD4C9E66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2F20FF02-12AB-448B-BC78-DD76DD4C9E66}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2F20FF02-12AB-448B-BC78-DD76DD4C9E66}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2F20FF02-12AB-448B-BC78-DD76DD4C9E66}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
2 changes: 2 additions & 0 deletions XmlSchemaClassGenerator/CodeUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -295,5 +295,7 @@ internal static string NormalizeNewlines(string text)
"using", "using static", "virtual", "void",
"volatile", "while"
};

internal static Uri CreateUri(string uri) => string.IsNullOrEmpty(uri) ? null : new Uri(uri);
}
}
16 changes: 8 additions & 8 deletions XmlSchemaClassGenerator/ModelBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ public ModelBuilder(GeneratorConfiguration configuration, XmlSchemaSet set)
foreach (var globalType in set.GlobalTypes.Values.Cast<XmlSchemaType>())
{
var schema = globalType.GetSchema();
var source = string.IsNullOrEmpty(schema?.SourceUri) ? null : new Uri(schema.SourceUri);
var source = CodeUtilities.CreateUri(schema?.SourceUri);
CreateTypeModel(source, globalType, globalType.QualifiedName);
}

foreach (var rootElement in set.GlobalElements.Values.Cast<XmlSchemaElement>())
{
var rootSchema = rootElement.GetSchema();
var source = !string.IsNullOrEmpty(rootSchema.SourceUri) ? new Uri(rootElement.GetSchema().SourceUri) : default(Uri);
var source = CodeUtilities.CreateUri(rootSchema.SourceUri);
var qualifiedName = rootElement.ElementSchemaType.QualifiedName;
if (qualifiedName.IsEmpty) { qualifiedName = rootElement.QualifiedName; }
var type = CreateTypeModel(source, rootElement.ElementSchemaType, qualifiedName);
Expand Down Expand Up @@ -165,7 +165,7 @@ private TypeModel CreateTypeModel(Uri source, XmlSchemaGroup group, NamespaceMod
var properties = CreatePropertiesForElements(source, interfaceModel, particle, items.Where(i => !(i.XmlParticle is XmlSchemaGroupRef)));
interfaceModel.Properties.AddRange(properties);
var interfaces = items.Select(i => i.XmlParticle).OfType<XmlSchemaGroupRef>()
.Select(i => (InterfaceModel)CreateTypeModel(new Uri(i.SourceUri), Groups[i.RefName], i.RefName));
.Select(i => (InterfaceModel)CreateTypeModel(CodeUtilities.CreateUri(i.SourceUri), Groups[i.RefName], i.RefName));
interfaceModel.Interfaces.AddRange(interfaces);

return interfaceModel;
Expand All @@ -192,7 +192,7 @@ private TypeModel CreateTypeModel(Uri source, XmlSchemaAttributeGroup attributeG
var properties = CreatePropertiesForAttributes(source, interfaceModel, items.OfType<XmlSchemaAttribute>());
interfaceModel.Properties.AddRange(properties);
var interfaces = items.OfType<XmlSchemaAttributeGroupRef>()
.Select(a => (InterfaceModel)CreateTypeModel(new Uri(a.SourceUri), AttributeGroups[a.RefName], a.RefName));
.Select(a => (InterfaceModel)CreateTypeModel(CodeUtilities.CreateUri(a.SourceUri), AttributeGroups[a.RefName], a.RefName));
interfaceModel.Interfaces.AddRange(interfaces);

return interfaceModel;
Expand Down Expand Up @@ -254,7 +254,7 @@ private TypeModel CreateTypeModel(Uri source, XmlSchemaComplexType complexType,
if (_configuration.GenerateInterfaces)
{
var interfaces = items.Select(i => i.XmlParticle).OfType<XmlSchemaGroupRef>()
.Select(i => (InterfaceModel)CreateTypeModel(new Uri(i.SourceUri), Groups[i.RefName], i.RefName));
.Select(i => (InterfaceModel)CreateTypeModel(CodeUtilities.CreateUri(i.SourceUri), Groups[i.RefName], i.RefName));
classModel.Interfaces.AddRange(interfaces);
}

Expand Down Expand Up @@ -283,7 +283,7 @@ private TypeModel CreateTypeModel(Uri source, XmlSchemaComplexType complexType,
if (_configuration.GenerateInterfaces)
{
var attributeInterfaces = attributes.OfType<XmlSchemaAttributeGroupRef>()
.Select(i => (InterfaceModel)CreateTypeModel(new Uri(i.SourceUri), AttributeGroups[i.RefName], i.RefName));
.Select(i => (InterfaceModel)CreateTypeModel(CodeUtilities.CreateUri(i.SourceUri), AttributeGroups[i.RefName], i.RefName));
classModel.Interfaces.AddRange(attributeInterfaces);
}
}
Expand Down Expand Up @@ -463,7 +463,7 @@ private IEnumerable<PropertyModel> CreatePropertiesForAttributes(Uri source, Typ
{
if (_configuration.GenerateInterfaces)
{
CreateTypeModel(new Uri(attributeGroupRef.SourceUri), AttributeGroups[attributeGroupRef.RefName], attributeGroupRef.RefName);
CreateTypeModel(CodeUtilities.CreateUri(attributeGroupRef.SourceUri), AttributeGroups[attributeGroupRef.RefName], attributeGroupRef.RefName);
}

var groupItems = AttributeGroups[attributeGroupRef.RefName].Attributes;
Expand Down Expand Up @@ -552,7 +552,7 @@ private IEnumerable<PropertyModel> CreatePropertiesForElements(Uri source, TypeM
{
if (_configuration.GenerateInterfaces)
{
CreateTypeModel(new Uri(groupRef.SourceUri), Groups[groupRef.RefName], groupRef.RefName);
CreateTypeModel(CodeUtilities.CreateUri(groupRef.SourceUri), Groups[groupRef.RefName], groupRef.RefName);
}

var groupItems = GetElements(groupRef.Particle);
Expand Down
12 changes: 11 additions & 1 deletion XmlSchemaClassGenerator/TypeModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml;
Expand Down Expand Up @@ -209,6 +210,11 @@ public override CodeTypeDeclaration Generate()

interfaceDeclaration.IsInterface = true;
interfaceDeclaration.IsPartial = true;
if (Configuration.AssemblyVisible)
{
interfaceDeclaration.TypeAttributes = (interfaceDeclaration.TypeAttributes & ~System.Reflection.TypeAttributes.VisibilityMask) | System.Reflection.TypeAttributes.NestedAssembly;
}


foreach (var property in Properties)
property.AddInterfaceMembersTo(interfaceDeclaration);
Expand Down Expand Up @@ -1126,6 +1132,10 @@ public override CodeTypeDeclaration Generate()
GenerateTypeAttribute(enumDeclaration);

enumDeclaration.IsEnum = true;
if (Configuration.AssemblyVisible)
{
enumDeclaration.TypeAttributes = (enumDeclaration.TypeAttributes & ~System.Reflection.TypeAttributes.VisibilityMask) | System.Reflection.TypeAttributes.NestedAssembly;
}

foreach (var val in Values)
{
Expand Down Expand Up @@ -1277,7 +1287,7 @@ public override CodeExpression GetDefaultValueFor(string defaultString, bool att
}


return new CodePrimitiveExpression(Convert.ChangeType(defaultString, ValueType));
return new CodePrimitiveExpression(Convert.ChangeType(defaultString, ValueType, CultureInfo.InvariantCulture));
}

public IEnumerable<CodeAttributeDeclaration> GetRestrictionAttributes()
Expand Down
2 changes: 1 addition & 1 deletion XmlSchemaClassGenerator/XmlSchemaClassGenerator.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<AssemblyTitle>XmlSchemaClassGenerator</AssemblyTitle>
<VersionPrefix>1.0.0-VERSION</VersionPrefix>
<Authors>Michael Ganss</Authors>
<TargetFrameworks>net45;netstandard2.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<AssemblyName>XmlSchemaClassGenerator</AssemblyName>
<PackageId>XmlSchemaClassGenerator-beta</PackageId>
<PackageTags>xsd</PackageTags>
Expand Down
3 changes: 3 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ build_script:
- ps: (Get-Content XmlSchemaClassGenerator\XmlSchemaClassGenerator.csproj).Replace("1.0.0-VERSION", $env:APPVEYOR_BUILD_VERSION) | Set-Content XmlSchemaClassGenerator\XmlSchemaClassGenerator.csproj
- ps: (Get-Content XmlSchemaClassGenerator.Console\XmlSchemaClassGenerator.Console.csproj).Replace("1.0.0-VERSION", $env:APPVEYOR_BUILD_VERSION) | Set-Content XmlSchemaClassGenerator.Console\XmlSchemaClassGenerator.Console.csproj
- ps: (Get-Content xscgen\xscgen.csproj).Replace("1.0.0-VERSION", $env:APPVEYOR_BUILD_VERSION) | Set-Content xscgen\xscgen.csproj
- ps: (Get-Content xscgen-proj\xscgen-proj.csproj).Replace("1.0.0-VERSION", $env:APPVEYOR_BUILD_VERSION) | Set-Content xscgen-proj\xscgen-proj.csproj
- dotnet --info
- dotnet restore
- dotnet build -c Release
- dotnet publish XmlSchemaClassGenerator.Console -c Release -f net45
- dotnet pack --include-symbols --include-source -c Release XmlSchemaClassGenerator
- dotnet pack --include-symbols --include-source -c Release XmlSchemaClassGenerator.Console
- dotnet pack --include-symbols --include-source -c Release xscgen
- dotnet pack --include-symbols --include-source -c Release xscgen-proj
- 7z a -mx=9 XmlSchemaClassGenerator.%APPVEYOR_BUILD_VERSION%.zip ".\XmlSchemaClassGenerator.Console\bin\Release\net45\publish\*"
test_script:
- ps: |
Expand All @@ -38,6 +40,7 @@ artifacts:
- path: 'XmlSchemaClassGenerator\**\*.nupkg'
- path: 'XmlSchemaClassGenerator.Console\**\*.nupkg'
- path: 'xscgen\**\*.nupkg'
- path: 'xscgen-proj\**\*.nupkg'
- path: XmlSchemaClassGenerator.%APPVEYOR_BUILD_VERSION%.zip
on_success:
- ps: |
Expand Down
34 changes: 34 additions & 0 deletions xscgen-proj/xscgen-proj.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<Description>A .NET Core CLI tool to generate XmlSerializer compatible C# classes from XML Schema files.</Description>
<Copyright>Copyright 2013-2018 Michael Ganss</Copyright>
<AssemblyTitle>xscgen</AssemblyTitle>
<VersionPrefix>1.0.0-VERSION</VersionPrefix>
<AssemblyName>dotnet-xscgen</AssemblyName>
<RootNamespace>XmlSchemaClassGenerator.Console</RootNamespace>
<Authors>Michael Ganss</Authors>
<PackageId>dotnet-xscgen-proj</PackageId>
<PackageTags>xsd xmlschema generator</PackageTags>
<PackageProjectUrl>https://github.com/mganss/XmlSchemaClassGenerator</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/mganss/XmlSchemaClassGenerator/blob/master/LICENSE</PackageLicenseUrl>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>git://github.com/mganss/XmlSchemaClassGenerator</RepositoryUrl>
<ToolCommandName>dotnet-xscgen</ToolCommandName>
<DefineConstants>$(DefineConstants);NETSTANDARD</DefineConstants>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\XmlSchemaClassGenerator\XmlSchemaClassGenerator.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\XmlSchemaClassGenerator.Console\**\*.cs" Exclude="..\XmlSchemaClassGenerator.Console\obj\**\*;..\XmlSchemaClassGenerator.Console\bin\**\*" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Glob.cs" Version="2.0.13" />
<PackageReference Include="Mono.Options" Version="5.3.0.1" />
</ItemGroup>
<PropertyGroup>
<SonarQubeExclude>true</SonarQubeExclude>
</PropertyGroup>
</Project>

0 comments on commit c19f626

Please sign in to comment.