public void Generate(UblGeneratorOptions options) { Console.WriteLine("Validating options..."); _options = options; options.Validate(); var baseInputDirectory = options.XsdBasePath; var maindocfiles = new List <FileInfo>(); if (!string.IsNullOrEmpty(baseInputDirectory)) { maindocfiles = new DirectoryInfo(baseInputDirectory).GetFiles("*.xsd").ToList(); } var maindocSchemaSet = new XmlSchemaSet() { // XmlResolver = xsdResolver // XmlResolver = null }; Console.WriteLine("Read common UBL files from embedded resources..."); var nameTable = new NameTable(); var readerSettings = new XmlReaderSettings { ValidationType = ValidationType.Schema, DtdProcessing = DtdProcessing.Parse, NameTable = nameTable }; AddCommonFiles(maindocSchemaSet, readerSettings); Console.WriteLine($"Add schema files from {baseInputDirectory}..."); var schemasToGenerate = new List <XmlSchema>(); foreach (var maindocfile in maindocfiles) { using (var reader = XmlReader.Create(maindocfile.FullName, readerSettings)) { var schema = XmlSchema.Read(reader, null); // ReplaceKnownSchemaIncludes(schema, knownSchema); maindocSchemaSet.Add(schema); schemasToGenerate.Add(schema); } } Console.WriteLine("Fixing schema..."); maindocSchemaSet.Compile(); foreach (var schemaFixer in _schemaFixers) { schemaFixer(maindocSchemaSet); maindocSchemaSet.Compile(); } Console.WriteLine("Creating compile unit..."); var namespaceProvider = new CodeNamespaceProvider(maindocSchemaSet, options); var compileUnit = CreateCodeNamespace(maindocSchemaSet, namespaceProvider); foreach (var ns in compileUnit.Namespaces.OfType <CodeNamespace>()) { _globalCodeFixer.Fix(ns); } var codeProvider = new CSharpCodeProvider(); var codegenOptions = new CodeGeneratorOptions() { BracingStyle = "C", IndentString = " ", BlankLinesBetweenMembers = true, VerbatimOrder = true }; Console.WriteLine("Generating source files..."); if (options.GenerateCommonFiles) { foreach (var schema in maindocSchemaSet.Schemas().Cast <XmlSchema>()) { GenerateCodeForSchema(options, compileUnit, namespaceProvider, codeProvider, codegenOptions, schema); } } else { foreach (var schema in schemasToGenerate) { GenerateCodeForSchema(options, compileUnit, namespaceProvider, codeProvider, codegenOptions, schema); } } }
private void GenerateCodeForSchema(UblGeneratorOptions options, CodeCompileUnit compileUnit, CodeNamespaceProvider namespaceProvider, CSharpCodeProvider codeProvider, CodeGeneratorOptions codegenOptions, XmlSchema schema) { var tmpCodeNamespace = compileUnit.Namespaces.OfType <CodeNamespace>().Single(x => x.UserData[CodeTypeMemberExtensions.XmlSchemaKey] == schema); var codeDeclsBySchema = (from t in tmpCodeNamespace.Types.Cast <CodeTypeDeclaration>() group t by t.GetSchema() into g select g) .ToDictionary(k => k.Key, v => v.ToArray()); var codeNamespace = namespaceProvider.CreateCodeNamespace(schema); if (codeDeclsBySchema.ContainsKey(schema)) { codeNamespace.Types.AddRange(codeDeclsBySchema[schema]); } if (codeNamespace.Types.Count == 0) { return; } _namespacedCodeFixer.Fix(codeNamespace); var sb = new StringBuilder(); using (var sw = new StringWriter(sb)) { codeProvider.GenerateCodeFromNamespace(codeNamespace, sw, codegenOptions); } sb = sb.Replace("Namespace=\"", "Namespace = \""); var fileContent = sb.ToString(); var lines = fileContent.Split(new[] { Environment.NewLine }, StringSplitOptions.None).ToList(); foreach (var fixer in _conditionalFeatureFixers) { int lineNum = 0; while (true) { lineNum = fixer(lines, lineNum); if (lineNum < 0) { break; } } } sb = new StringBuilder(string.Join(Environment.NewLine, lines)); var xsdFilename = new Uri(schema.SourceUri).LocalPath; var fi = new FileInfo(xsdFilename); var foldername = namespaceProvider.GetNamespaceFolderName(schema); string targetPath = Path.Combine(options.OutputPath, foldername); if (!Directory.Exists(targetPath)) { Directory.CreateDirectory(targetPath); } var outputFile = Path.Combine(targetPath, Path.ChangeExtension(fi.Name, ".generated.cs")); using (var ofile = File.CreateText(outputFile)) { ofile.Write(sb); Console.WriteLine($"Written: {outputFile}"); } }
private CodeCompileUnit CreateCodeNamespace(XmlSchemaSet schemaSet, CodeNamespaceProvider namespaceProvider) { var compileUnit = new CodeCompileUnit(); var schemas = new XmlSchemas(); foreach (var s in schemaSet.Schemas()) { schemas.Add((XmlSchema)s); } schemas.Compile(_options.ValidationHandler, true); foreach (XmlSchema schema in schemas) { var codeNamespace = namespaceProvider.CreateCodeNamespace(schema); compileUnit.Namespaces.Add(codeNamespace); } var codeOptions = CodeGenerationOptions.GenerateOrder | CodeGenerationOptions.GenerateNewAsync; // foreach (var ns in rootNamespaces.Concat(extensionNamespaces)) foreach (XmlSchema schema in schemas) { var schemaImporter = new XmlSchemaImporter(schemas); schemaImporter.Extensions.Clear(); // var schema = schemas[ns]; var codeNamespace = compileUnit.Namespaces.OfType <CodeNamespace>().Single(x => x.UserData[CodeTypeMemberExtensions.XmlSchemaKey] == schema); Console.WriteLine($"Import root namespace: {schema.TargetNamespace}"); var codeExporter = new XmlCodeExporter(codeNamespace, compileUnit, codeOptions); foreach (XmlSchemaElement element in schema.Elements.Values.OfType <XmlSchemaElement>()) { Console.WriteLine($"Import type mapping for {element.QualifiedName.Namespace} : {element.QualifiedName.Name}"); var xmlTypeMapping = schemaImporter.ImportTypeMapping(element.QualifiedName); codeExporter.ExportTypeMapping(xmlTypeMapping); } var baseTypes = schema.Elements.Values.OfType <XmlSchemaElement>().Select(x => x.SchemaTypeName.Name).ToList(); foreach (XmlSchemaComplexType element in schema.SchemaTypes.Values.OfType <XmlSchemaComplexType>().Where(x => !baseTypes.Contains(x.Name))) { Console.WriteLine($"Import schema type for {element.QualifiedName.Namespace} : {element.QualifiedName.Name}"); var xmlTypeMapping = schemaImporter.ImportSchemaType(element.QualifiedName); codeExporter.ExportTypeMapping(xmlTypeMapping); } } var codeDeclarations = compileUnit.Namespaces.OfType <CodeNamespace>().SelectMany(x => x.Types.Cast <CodeTypeDeclaration>()).ToList(); foreach (var codeDecl in codeDeclarations) { codeDecl.Comments.Clear(); foreach (var item in codeDecl.Members.OfType <CodeTypeMember>()) { item.Comments.Clear(); } var qname = codeDecl.GetQualifiedName(); codeDecl.UserData[CodeTypeMemberExtensions.QualifiedNameKey] = qname; // Note, this can fail when there are multiple schemas for one namespace, like urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2 var schema = schemas.GetSchemas(qname.Namespace).OfType <XmlSchema>().FirstOrDefault(); // var schema = schemas[qname.Namespace]; codeDecl.UserData[CodeTypeMemberExtensions.XmlSchemaKey] = schema; var xmlSchemaType = (XmlSchemaType)schema.SchemaTypes[qname]; codeDecl.UserData[CodeTypeMemberExtensions.XmlSchemaTypeKey] = xmlSchemaType; foreach (CodeTypeMember member in codeDecl.Members) { member.UserData[CodeTypeMemberExtensions.XmlSchemaKey] = schema; member.UserData[CodeTypeMemberExtensions.XmlSchemaTypeKey] = xmlSchemaType; } } return(compileUnit); }
public void Generate(UblGeneratorOptions options) { _options = options; options.Validate(); var baseInputDirectory = options.XsdBasePath; var commonDirectory = Path.Combine(baseInputDirectory, "common"); var xmldsigFilename = new DirectoryInfo(commonDirectory).GetFiles("UBL-xmldsig-core-schema-*.xsd").Single().FullName; var maindocDirectory = Path.Combine(baseInputDirectory, "maindoc"); var maindocfiles = new DirectoryInfo(maindocDirectory).GetFiles("*.xsd").ToList(); // var extrafiles = new DirectoryInfo(commonDirectory).GetFiles("UBL-CommonSignatureComponents*.xsd").ToList(); // var maindocfiles = new DirectoryInfo(maindocDirectory).GetFiles("UBL-Order-2.1.xsd").ToList(); // maindocfiles.Add(new DirectoryInfo(maindocDirectory).GetFiles("UBL-BaseDocument-*.xsd").Single()); var maindocSchemaSet = new XmlSchemaSet(); var nameTable = new NameTable(); var readerSettings = new XmlReaderSettings { ValidationType = ValidationType.Schema, DtdProcessing = DtdProcessing.Parse, NameTable = nameTable, }; using (var reader = XmlReader.Create(xmldsigFilename, readerSettings)) { var schema = XmlSchema.Read(reader, null); maindocSchemaSet.Add(schema); } foreach (var maindocfile in maindocfiles) { using (var reader = XmlReader.Create(maindocfile.FullName, readerSettings)) { var schema = XmlSchema.Read(reader, null); maindocSchemaSet.Add(schema); } } //foreach (var extrafile in extrafiles) //{ // using (var reader = XmlReader.Create(extrafile.FullName, readerSettings)) // { // var schema = XmlSchema.Read(reader, null); // maindocSchemaSet.Add(schema); // } //} maindocSchemaSet.Compile(); foreach (var schemaFixer in _schemaFixers) { schemaFixer(maindocSchemaSet); maindocSchemaSet.Compile(); } var rootNamespaces = maindocSchemaSet.Schemas().OfType <XmlSchema>() .Where(x => x.SourceUri.Contains("maindoc")) .Select(x => x.TargetNamespace) .Concat(new[] { Namespaces.Xmldsig, Namespaces.Sac, Namespaces.Csc, Namespaces.Xades141, }); var tempCodeNamespace = CreateCodeNamespace(maindocSchemaSet, rootNamespaces.ToArray()); _globalCodeFixer.Fix(tempCodeNamespace); var codeDeclsBySchema = (from t in tempCodeNamespace.Types.Cast <CodeTypeDeclaration>() group t by t.GetSchema() into g select g) .ToDictionary(k => k.Key, v => v.ToArray()); var codeProvider = new Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider(); var codegenOptions = new CodeGeneratorOptions() { BracingStyle = "C", IndentString = " ", BlankLinesBetweenMembers = true, VerbatimOrder = true }; var namespaceProvider = new CodeNamespaceProvider(maindocSchemaSet, options); foreach (var schema in maindocSchemaSet.Schemas().Cast <XmlSchema>()) { var codeNamespace = namespaceProvider.CreateCodeNamespace(schema.TargetNamespace); if (codeDeclsBySchema.ContainsKey(schema)) { codeNamespace.Types.AddRange(codeDeclsBySchema[schema]); } if (codeNamespace.Types.Count == 0) { continue; } _namespacedCodeFixer.Fix(codeNamespace); var sb = new StringBuilder(); using (var sw = new StringWriter(sb)) { codeProvider.GenerateCodeFromNamespace(codeNamespace, sw, codegenOptions); } sb = sb.Replace("Namespace=\"", "Namespace = \""); var fileContent = sb.ToString(); var lines = fileContent.Split(new[] { Environment.NewLine }, StringSplitOptions.None).ToList(); foreach (var fixer in _conditionalFeatureFixers) { int lineNum = 0; while (true) { lineNum = fixer(lines, lineNum); if (lineNum < 0) { break; } } } sb = new StringBuilder(string.Join(Environment.NewLine, lines)); var xsdFilename = new Uri(schema.SourceUri).LocalPath; var fi = new FileInfo(xsdFilename); var foldername = namespaceProvider.GetNamespaceFolderName(schema); string targetPath = Path.Combine(options.OutputPath, foldername); if (!Directory.Exists(targetPath)) { Directory.CreateDirectory(targetPath); } var outputFile = Path.Combine(targetPath, Path.ChangeExtension(fi.Name, ".generated.cs")); using (var ofile = File.CreateText(outputFile)) { ofile.Write(sb); } } }