private void RemoveElements(CodeNamespace codeNamespace, IReadOnlyCollection <XmlSchema> inputs, UsageTree usageTree) { // Remove attributes foreach (CodeTypeDeclaration codeType in codeNamespace.Types) { var attributesToRemove = new HashSet <CodeAttributeDeclaration>(); foreach (CodeAttributeDeclaration att in codeType.CustomAttributes) { if (Options.AttributesToRemove.Contains(att.Name)) { attributesToRemove.Add(att); } else { switch (att.Name) { case "System.Xml.Serialization.XmlRootAttribute": var nullableArgument = att.Arguments.Cast <CodeAttributeArgument>().FirstOrDefault(x => x.Name == "IsNullable"); if (codeType.IsEnum || (nullableArgument != null && (bool)((CodePrimitiveExpression)nullableArgument.Value).Value)) { // Remove nullable root attribute attributesToRemove.Add(att); } break; } } } foreach (var att in attributesToRemove) { codeType.CustomAttributes.Remove(att); } } // Remove types if (Options.ExcludeImportedTypes && Options.Imports != null && Options.Imports.Count > 0) { var removedTypes = codeNamespace.Types.Cast <CodeTypeDeclaration>().ToList(); var anonymousTypes = new List <CodeTypeDeclaration>(); while (removedTypes.RemoveAll(codeType => { if ((codeType.IsAnonymousType() && !codeType.IsRootType()) || codeType.IsIncludeInSchemaFalse()) { if (!usageTree.LookupUsages(codeType).All(x => removedTypes.Contains(x.Type))) { return(true); } } else if (inputs.Any(schema => ContainsTypeName(schema, codeType))) { return(true); } return(false); }) > 0) { ; } // Remove types foreach (var rt in removedTypes) { codeNamespace.Types.Remove(rt); } } }
public void Generate(IList <String> schemas, TextWriter output) { if (Options == null) { Options = new XsdCodeGeneratorOptions { UseLists = true, PropertyNameCapitalizer = new FirstCharacterCapitalizer(), OutputNamespace = "Xsd2", UseNullableTypes = true, AttributesToRemove = { "System.Diagnostics.DebuggerStepThroughAttribute" } }; } if (Options.Imports != null) { foreach (var import in Options.Imports) { if (File.Exists(import)) { ImportImportedSchema(import); } else if (Directory.Exists(import)) { foreach (var file in Directory.GetFiles("*.xsd")) { ImportImportedSchema(file); } } else { throw new InvalidOperationException(String.Format("Import '{0}' is not a file nor a directory.", import)); } } } var inputs = new List <XmlSchema>(); foreach (var path in schemas) { using (var r = File.OpenText(path)) { XmlSchema xsd = XmlSchema.Read(r, null); xsds.Add(xsd); inputs.Add(xsd); } } xsds.Compile(null, true); XmlSchemaImporter schemaImporter = new XmlSchemaImporter(xsds); // create the codedom CodeNamespace codeNamespace = new CodeNamespace(Options.OutputNamespace); XmlCodeExporter codeExporter = new XmlCodeExporter(codeNamespace); List <XmlTypeMapping> maps = new List <XmlTypeMapping>(); foreach (var xsd in inputs) { foreach (XmlSchemaElement schemaElement in xsd.Elements.Values) { if (!ElementBelongsToImportedSchema(schemaElement) && !ExcludeName(schemaElement)) { maps.Add(schemaImporter.ImportTypeMapping(schemaElement.QualifiedName)); } } } foreach (var xsd in inputs) { foreach (XmlSchemaComplexType schemaElement in xsd.Items.OfType <XmlSchemaComplexType>()) { if (ExcludeName(schemaElement)) { continue; } maps.Add(schemaImporter.ImportSchemaType(schemaElement.QualifiedName)); } } foreach (var xsd in inputs) { foreach (XmlSchemaSimpleType schemaElement in xsd.Items.OfType <XmlSchemaSimpleType>()) { if (ExcludeName(schemaElement)) { continue; } maps.Add(schemaImporter.ImportSchemaType(schemaElement.QualifiedName)); } } foreach (XmlTypeMapping map in maps) { codeExporter.ExportTypeMapping(map); } ImproveCodeDom(codeNamespace); var usageTree = new UsageTree(codeNamespace); RemoveElements(codeNamespace, inputs, usageTree); if (OnValidateGeneratedCode != null) { foreach (var xsd in inputs) { OnValidateGeneratedCode(codeNamespace, xsd); } } // Check for invalid characters in identifiers CodeGenerator.ValidateIdentifiers(codeNamespace); if (Options.WriteFileHeader) { // output the header string lineCommentCharacter; switch (Options.Language) { case XsdCodeGeneratorOutputLanguage.VB: lineCommentCharacter = "'"; break; default: lineCommentCharacter = "//"; break; } output.WriteLine("{0}------------------------------------------------------------------------------", lineCommentCharacter); output.WriteLine("{0} <auto-generated>", lineCommentCharacter); output.WriteLine("{0} This code has been generated by a tool.", lineCommentCharacter); output.WriteLine("{0} </auto-generated>", lineCommentCharacter); output.WriteLine("{0}------------------------------------------------------------------------------", lineCommentCharacter); output.WriteLine(); } // output the C# code CodeDomProvider codeProvider; switch (Options.Language) { case XsdCodeGeneratorOutputLanguage.VB: codeProvider = new VBCodeProvider(); break; default: codeProvider = new CSharpCodeProvider(); break; } codeProvider.GenerateCodeFromNamespace(codeNamespace, output, new CodeGeneratorOptions()); }