如何以编程方式从类型生成xml架构?

我正在尝试以编程方式从任何.net类型生成xs:schema。 我知道我可以使用reflection并通过迭代公共属性来生成它,但是有内置的方法吗?

例:

[Serializable] public class Person { [XmlElement(IsNullable = false)] public string FirstName { get; set; } [XmlElement(IsNullable = false)] public string LastName { get; set; } [XmlElement(IsNullable = true)] public string PhoneNo { get; set; } } 

期望的输出:

           

我发现接受的答案会产生一些错误的模式,给出了我的一些属性。 例如,它忽略了标有[XmlEnum(Name="Foo")]枚举值的自定义名称

我相信这是正确的方法(鉴于你使用XmlSerializer ),也很简单:

 var schemas = new XmlSchemas(); var exporter = new XmlSchemaExporter(schemas); var mapping = new XmlReflectionImporter().ImportTypeMapping(typeof(Person)); exporter.ExportTypeMapping(mapping); var schemaWriter = new StringWriter(); foreach (XmlSchema schema in schemas) { schema.Write(schemaWriter); } return schemaWriter.ToString(); 

代码摘自: http : //blogs.msdn.com/b/youssefm/archive/2010/05/13/using-xml-schema-import-and-export-for-xmlserializer.aspx

所以这是有效的,我想它并不像看起来那么难看:

 var soapReflectionImporter = new SoapReflectionImporter(); var xmlTypeMapping = soapReflectionImporter.ImportTypeMapping(typeof(Person)); var xmlSchemas = new XmlSchemas(); var xmlSchema = new XmlSchema(); xmlSchemas.Add(xmlSchema); var xmlSchemaExporter = new XmlSchemaExporter(xmlSchemas); xmlSchemaExporter.ExportTypeMapping(xmlTypeMapping); 

我仍然希望那里有一个2线解决方案,似乎应该有,感谢提示@dtb


编辑只是为了踢,这里是2行版本(自我贬低幽默)

 var typeMapping = new SoapReflectionImporter().ImportTypeMapping(typeof(Person)); new XmlSchemaExporter(new XmlSchemas { new XmlSchema() }).ExportTypeMapping(typeMapping); 

您可以以编程方式调用xsd.exe

  1. xsd.exe添加为程序集引用。
  2. using XsdTool;
  3. Xsd.Main(new[] { "myassembly.dll", "/type:MyNamespace.MyClass" });

您还可以使用Reflector查看XsdTool.Xsd.ExportSchemas方法。 它使用公共XmlReflectionImporter , XmlSchemas , XmlSchema XmlSchemaExporter和XmlTypeMapping类从.NET类型创建模式。

基本上它是这样做的:

 var importer = new XmlReflectionImporter(); var schemas = new XmlSchemas(); var exporter = new XmlSchemaExporter(schemas); var xmlTypeMapping = importer.ImportTypeMapping(typeof(Person)); exporter.ExportTypeMapping(xmlTypeMapping); schemas.Compile(..., false); for (var i = 0; i < schemas.Count; i++) { var schema = schemas[i]; schema.Write(...); } ↑ 

您应该能够通过将合适的编写器传递给XmlSchema.Write方法来自定义输出。

我相信这就是你要找的: 编写自己的XSD.exe

借用上面的代码:

 using System; using System.IO; using System.Collections.Generic; using System.Reflection; using System.Text; using System.Xml; using System.Xml.Serialization; using System.Xml.Schema; using System.CodeDom; using System.CodeDom.Compiler; using Microsoft.CSharp; using NUnit.Framework; namespace XmlSchemaImporterTest { [TestFixture] public class XsdToClassTests { // Test for XmlSchemaImporter [Test] public void XsdToClassTest() { // identify the path to the xsd string xsdFileName = "Account.xsd"; string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string xsdPath = Path.Combine(path, xsdFileName); // load the xsd XmlSchema xsd; using(FileStream stream = new FileStream(xsdPath, FileMode.Open, FileAccess.Read)) { xsd = XmlSchema.Read(stream, null); } Console.WriteLine("xsd.IsCompiled {0}", xsd.IsCompiled); XmlSchemas xsds = new XmlSchemas(); xsds.Add(xsd); xsds.Compile(null, true); XmlSchemaImporter schemaImporter = new XmlSchemaImporter(xsds); // create the codedom CodeNamespace codeNamespace = new CodeNamespace("Generated"); XmlCodeExporter codeExporter = new XmlCodeExporter(codeNamespace); List maps = new List(); 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); } RemoveAttributes(codeNamespace); // Check for invalid characters in identifiers CodeGenerator.ValidateIdentifiers(codeNamespace); // output the C# code CSharpCodeProvider codeProvider = new CSharpCodeProvider(); using(StringWriter writer = new StringWriter()) { codeProvider.GenerateCodeFromNamespace(codeNamespace, writer, new CodeGeneratorOptions()); Console.WriteLine(writer.GetStringBuilder().ToString()); } Console.ReadLine(); } // Remove all the attributes from each type in the CodeNamespace, except // System.Xml.Serialization.XmlTypeAttribute private void RemoveAttributes(CodeNamespace codeNamespace) { foreach(CodeTypeDeclaration codeType in codeNamespace.Types) { CodeAttributeDeclaration xmlTypeAttribute = null; foreach(CodeAttributeDeclaration codeAttribute in codeType.CustomAttributes) { Console.WriteLine(codeAttribute.Name); if(codeAttribute.Name == "System.Xml.Serialization.XmlTypeAttribute") { xmlTypeAttribute = codeAttribute; } } codeType.CustomAttributes.Clear(); if(xmlTypeAttribute != null) { codeType.CustomAttributes.Add(xmlTypeAttribute); } } } } } 

XML Schema Definition工具从XDR,XML和XSD文件或运行时程序集中的类生成XML模式或公共语言运行时类。

http://msdn.microsoft.com/en-us/library/x6c1kb0s(VS.71).aspx