2010-09-09 11 views
12

मैं एक xs उत्पन्न करने की कोशिश कर रहा हूं: किसी भी .net से स्कीमा प्रोग्रामेटिक रूप से टाइप करें। मुझे पता है कि मैं प्रतिबिंब का उपयोग कर सकता हूं और इसे सार्वजनिक गुणों पर पुन: उत्पन्न करके उत्पन्न कर सकता हूं, लेकिन क्या वहां कोई अंतर्निहित है?मैं प्रोग्राम प्रकार से एक प्रकार से एक्सएमएल स्कीमा कैसे उत्पन्न करूं?

उदाहरण:

[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; } 
} 

वांछित आउटपुट:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="Person" type="Person" /> 
    <xs:complexType name="Person"> 
    <xs:sequence> 
     <xs:element minOccurs="0" maxOccurs="1" form="unqualified" name="FirstName" type="xs:string" /> 
     <xs:element minOccurs="0" maxOccurs="1" form="unqualified" name="LastName" type="xs:string" /> 
     <xs:element minOccurs="0" maxOccurs="1" form="unqualified" name="PhoneNo" type="xs:string" /> 
    </xs:sequence> 
    </xs:complexType> 
</xs:schema> 
+0

मैं:

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

कोड से निकाला संदेह है कि सामान्य मामले में ऐसा करने का एक तरीका है। इसके अलावा, एक्सएमएल सीरिएलाइज़र द्वारा '[Serializable]' का उपयोग नहीं किया जाता है। –

+0

@ जॉन को यह नहीं पता था, धन्यवाद! –

उत्तर

9

तो यह काम करता है, मुझे लगता है कि यह के रूप में बदसूरत के रूप में यह लग रहा था नहीं था:

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


संपादित बस kic के लिए (स्वयं पर हंसने) ks, यहाँ 2 लाइन संस्करण है

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

मैंने अभी खुद को आपके जैसी समस्या में पाया है। मैंने आपके कोड का उपयोग करने की कोशिश की है, 'नई स्कीमा() 'को पहले से मौजूद' एक्सएमएलशेमा 'चर के साथ बदल दिया है, लेकिन यह काम नहीं करता है। क्या आप आगे बता सकते हैं कि आपका समाधान कैसे काम करता है? – pyon

+0

क्या पहले से मौजूद एक्सएमएलशेमा में कुछ भी है? साबुन प्रतिबिंब आयातक एक आंतरिक वर्ग है जो वेब सेवाओं के लिए नेट फ्रेमवर्क द्वारा उपयोग किया जाता है, मुझे विश्वास है। इसमें कुछ एमएसडीएन दस्तावेज है। –

+0

हाय, मैं बस एक [संपादित करें] को अस्वीकार करने वाला हूं (http://stackoverflow.com/suggested-edits/266125) क्योंकि यह आपके कोड को संशोधित करता है। आप यह देखने के लिए (या संबंधित टिप्पणी आउट) जांचना चाहेंगे कि वे वैध हैं या नहीं। – Benjol

6

आप प्रोग्राम के रूप में xsd.exe आह्वान कर सकते हैं:

  1. विधानसभा संदर्भ के रूप में xsd.exe जोड़ें।
  2. using XsdTool;
  3. Xsd.Main(new[] { "myassembly.dll", "/type:MyNamespace.MyClass" });

तुम भी परावर्तक का उपयोग XsdTool.Xsd.ExportSchemas विधि को देखने के लिए कर सकते हैं। यह सार्वजनिक XmlReflectionImporter, XmlSchemas, XmlSchemaXmlSchemaExporter और 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 विधि करने के लिए एक उपयुक्त लेखक पारित करके उत्पादन अनुकूलित करने के लिए सक्षम होना चाहिए।

+0

यह दिलचस्प है, मुझे नहीं पता था कि आप ऐसा कर सकते हैं। वास्तव में मैं जो खोज रहा हूं वह नहीं। इसे प्रोग्रामेटिक रूप से करने का कारण आउटपुट को नियंत्रित करना होगा। –

+0

मैंने वास्तव में पहले ही ऐसा किया है। यह एक क्लस्टर का प्रकार है, मैं उम्मीद कर रहा था कि कोई बेहतर तरीके से जानता था। –

0

एक्सएमएल स्कीमा परिभाषा उपकरण एक्सडीआरआर, एक्सएमएल, और एक्सएसडी फाइलों से एक्सएमएल स्कीमा या सामान्य भाषा रनटाइम कक्षाएं उत्पन्न करता है, या रनटाइम असेंबली में कक्षाओं से उत्पन्न करता है।

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

+1

एक .exe चलाना प्रोग्रामैटिक के रूप में नहीं गिना जाता है। –

+0

आप हमेशा अपने कोड से .exe चला सकते हैं। ;) – JBeurer

1

मुझे इस पर विश्वास है क्या आप देख रहे हैं: ऊपर से Writing your own 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); 
       } 
      } 
     } 
    } 
} 
+1

निश्चित रूप से अब तक आप एक लिंक-केवल उत्तर पोस्ट करने से बेहतर जानते हैं? –

+1

@ जॉन सैंडर्स: मैंने इसे पोस्ट करने से कुछ मिनट पहले बहस की, लेकिन मुझे एक उपयोगी सारांश नहीं मिला (ब्लॉग के लिए पूरे कार्यक्रम को पोस्ट करने के अलावा)। इसके साथ ही जोखिम यह है कि यह पोस्ट वहां से किसी भी अपडेट के साथ सिंक हो रही है। आप क्या सलाह देते हैं? – Mrchief

+0

आपके लिए इसे हटाने से पहले इसे हटाने से मेरी सिफारिश होगी, जब तक आप सारांश के साथ नहीं आ सकते। –

13

मैंने पाया accepted answer ने मेरे कुछ विशेषताओं को एक गलत स्कीमा उत्पन्न किया। जैसेयह enum मूल्यों [XmlEnum(Name="Foo")]

के साथ चिह्नित मेरा मानना ​​है कि यह सही तरीका (आपका का उपयोग कर XmlSerializer दिया) है के लिए कस्टम नाम नजरअंदाज कर दिया और भी काफी सरल है: http://blogs.msdn.com/b/youssefm/archive/2010/05/13/using-xml-schema-import-and-export-for-xmlserializer.aspx

+0

चीयर्स, अद्यतन के लिए धन्यवाद। –

संबंधित मुद्दे