Des modèles T4 sont-ils disponibles pour générer des classes C# à partir de xsd?Y at-il des modèles T4 disponibles pour générer des classes C# à partir de xsd?
4
A
Répondre
3
Pas que je sache, mais jetez un oeil à LINQ à XSD (http://linqtoxsd.codeplex.com/). Vous pouvez utiliser LinqToXsd.exe pour générer des classes fortement typées en fonction de votre schéma. Et puis vous avez également un support LINQ complet. Très utile.
Vous pouvez également mettre en place un événement pré-construction de votre projet qui ressemble à quelque chose comme:
"$(ProjectDir)Lib/LinqToXsd/LinqToXsd.Exe" "$(ProjectDir)MySchema.xsd" /fileName:MySchema.cs
Et cela générer les classes du schéma à droite avant de construire, donc si vous changez schéma, vos classes resteront synchronisées avec chaque build.
3
Je viens de construire un très simple aujourd'hui qui devrait faire l'affaire.
<#@ template debug="true" hostSpecific="true" #>
<#@ Assembly Name="System.Core.dll" #>
<#@ Assembly Name="System.Windows.Forms.dll" #>
<#@ Assembly Name="System.Xml" #>
<#@ Assembly Name="Microsoft.CSharp" #>
<#@ output extension=".txt" #>
<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Xml.Serialization" #>
<#@ import namespace="System.Xml.Schema" #>
<#@ import namespace="System.CodeDom" #>
<#@ import namespace="System.CodeDom.Compiler" #>
<#@ import namespace="Microsoft.CSharp" #>
<#
// directory of this template
var outputDirectory = Path.GetDirectoryName(Host.TemplateFile);
// iterate through each XSD file in our /Schema/ directory
// and output the generated C# file in this directory.
foreach(var file in new DirectoryInfo(Host.ResolvePath("Schemas")).GetFiles("*.xsd")) {
// ouput file should be the directory of this template, with .Generated.cs
var outputFile = Path.Combine(outputDirectory, file.Name.Replace(".xsd", ".Generated.cs"));
// do it
File.WriteAllText(outputFile, GenerateFromXsd(file.FullName));
}
#>
<#+
private string GenerateFromXsd(string xsdFileName)
{
// load the xsd
XmlSchema xsd;
using (FileStream stream = new FileStream(xsdFileName, FileMode.Open, FileAccess.Read))
{
xsd = XmlSchema.Read(stream, null);
}
var xsds = new XmlSchemas();
xsds.Add(xsd);
xsds.Compile(null, true);
var schemaImporter = new XmlSchemaImporter(xsds);
// create the codedom
var codeNamespace = new CodeNamespace((string)System.Runtime.Remoting.Messaging.CallContext.LogicalGetData("NamespaceHint"));
var codeExporter = new XmlCodeExporter(codeNamespace);
var maps = new List<object>();
foreach (XmlSchemaType schemaType in xsd.SchemaTypes.Values)
{
maps.Add(schemaImporter.ImportSchemaType(schemaType.QualifiedName));
}
foreach (XmlSchemaElement schemaElement in xsd.Elements.Values)
{
maps.Add(schemaImporter.ImportTypeMapping(schemaElement.QualifiedName));
}
foreach (XmlTypeMapping map in maps)
{
codeExporter.ExportTypeMapping(map);
}
// Check for invalid characters in identifiers
CodeGenerator.ValidateIdentifiers(codeNamespace);
// output the C# code
var codeProvider = new CSharpCodeProvider();
using (var writer = new StringWriter())
{
codeProvider.GenerateCodeFromNamespace(codeNamespace, writer, new CodeGeneratorOptions());
return writer.GetStringBuilder().ToString();
}
}
#>
Nice, je ne le savais pas. Beaucoup mieux qu'une étape de pré-construction. –
Vous pouvez également utiliser la propriété Action de construction du fichier XSD dans l'Explorateur de solutions et la définir sur LinqToXsdSchema (cela nécessite que vous configuriez le projet pour importer LinqToXsd.targets) –