2010-07-01 8 views

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.

+0

Nice, je ne le savais pas. Beaucoup mieux qu'une étape de pré-construction. –

+1

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) –

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(); 
     } 
    } 
#>