2017-02-21 7 views
7

हम भविष्य में हमारी परियोजनाओं के लिए एफ # का लाभ उठाने की सोच रहे हैं, और स्वचालित रूप से एफ # प्रकारों से .xsd स्कीमा जेनरेट करने में सक्षम होना चाहते हैं।क्या F # प्रकारों के लिए .xsd उत्पन्न करने का कोई तरीका है?

वेब खोजना .xsd से प्रकार उत्पन्न करने के लिए बहुत सारे उत्तरों देता है, लेकिन दूसरी तरफ नहीं।

क्या कोई इसे करने का तरीका जानता है?

उत्तर

4

उस तरह का निर्भर करता है कि आप वास्तव में क्या मतलब रखते हैं।

यदि आपका मतलब था: "मैं डीएल से एक्सएसडी कैसे उत्पन्न करूं?" तो इसे svcutil के साथ काफी आसानी से किया जा सकता है ... ठीक है, यह देखते हुए कि कुछ अन्य स्थितियों को पूरा किया जाता है, लेकिन काम करने योग्य:

निम्न आदेश सेवा अनुबंधों और असेंबली में संबंधित प्रकारों के लिए मेटाडेटा दस्तावेज़ उत्पन्न करता है।

svcutil myAssembly.dll 

https://msdn.microsoft.com/en-us/library/aa347733(v=vs.110).aspx

xsd.exe भी तरह का एक ही के बारे में ऐसा करने में सक्षम होना चाहिए। मैं यहां क्या स्थितियों के तहत निश्चित नहीं हूं, लेकिन दस्तावेज़ svcutil के रूप में इतना "कड़े" नहीं हैं।

निम्न आदेश असेंबली myAssembly.dll में सभी प्रकार के लिए एक्सएमएल स्कीमा जेनरेट करता है और उन्हें वर्तमान निर्देशिका में schema0.xsd के रूप में सहेजता है।

xsd myAssembly.dll 

https://msdn.microsoft.com/en-us/library/x6c1kb0s(v=vs.110).aspx

यदि आप का मतलब तो आप (मेरी जानकारी के लिए) के भाग्य से बाहर दयालु हैं "फ़ाइल दिया * .fs से XSD उत्पन्न"।

+0

आपके उत्तर के लिए धन्यवाद, हेल्ज। हम वास्तव में एफ # प्रकार के लिए .xsd उत्पन्न करना चाहते हैं, और अंतर्निहित सीएलआई प्रकार नहीं, एफ # की संक्षिप्तता का लाभ उठाने के लिए। हम यह देखने के लिए एक .dll के माध्यम से दृष्टिकोण का प्रयास करेंगे कि यह कैसा दिखता है, लेकिन फिर भी उम्मीद है कि एक और प्रत्यक्ष मैपिंग उपलब्ध है। –

0

मैं गलत हो सकता था, लेकिन मुझे नहीं लगता कि यह कैसे किया जा सकता है, यह एक तरीके से पूरा किया जा सकता है जो एक्सएसडी के आधार पर एफ # प्रकार प्रदाता का उपयोग करने से अधिक व्यावहारिक बना देगा, यदि कोई ऐसा व्यक्ति है जो पर्याप्त रूप से अच्छी तरह से काम करता है। लेकिन फिर, मुझे यकीन नहीं है कि एक है।

FSharp.Data.Xsd प्रकार प्रदाता का प्रयास करें। आप स्ट्रिंग के रूप में स्रोत में एक्सएसडी सही निर्दिष्ट कर सकते हैं, या स्रोत के बाहर बाहरी एक्सएसडी फ़ाइल का संदर्भ देकर। यह संभव है कि यह कोई भी एक्सएसडी नहीं बना सकता जो आप चाहें।

समस्या, मुझे लगता है कि यह है कि एफ # प्रकार अकेले यह निर्दिष्ट करने का व्यावहारिक तरीका नहीं है कि एक्सएसडी कैसा दिखना चाहिए, जब तक कि आप कुछ समझौता नहीं करते हैं कि शायद आप बनाने के लिए तैयार नहीं हैं।

  • क्या आप मैपिंग को नियंत्रित करने के लिए F # में कुछ विशिष्ट प्रकार बनाएंगे? मुझे नहीं लगता कि इस तरह के उपयोग करने के लिए "एफ # लीवरेज" होगा।

  • क्या आप कोड विशेषताएँ या अन्य मेटाडेटा का उपयोग करेंगे? उस स्थिति में, एफ # प्रकारों के बजाय एक्सएसडी को बेहतर तरीके से संपादित नहीं कर रहा है?

  • क्या आप बस कुछ नियम बनायेंगे जो एक-से-एक मैपिंग का संकेत देते हैं? यह काम कर सकता है, लेकिन हो सकता है कि आप एक्सएसडी और एक्सएमएल का उत्पादन न करें। यह भी वर्बोज़ बन सकता है।

आपको एक्सएसडी उत्पन्न करना होगा। यदि दूसरी तरफ आप एक्सएसडी से एफ # प्रकार उत्पन्न करने के लिए एक प्रकार प्रदाता का उपयोग करते हैं, तो जेनरेट किए गए प्रकार तुरंत उपलब्ध होते हैं।क्या यह ज्यादा व्यावहारिक और प्रसन्न नहीं है?

0

मैं 'टाइपक्लास' का उपयोग करके इस पर पहुंचूंगा। त्वरित उदाहरण (आरईपीएल में)। मान लें कि आपके पास Person प्रकार है, जैसे type Person = { id : int64; name : string}। तब:

> ("id", Xsd.int64, "name", Xsd.string) 
    |> Xsd.record2 "Person" 
    |> Xsd.root 
    |> Xsd.to_string;; 
val it : string = 
    "<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <xsd:complexType name="Person"> 
    <xsd:sequence> 
    <xsd:element name="id" type="long"/> 
    <xsd:element name="name" type="string"/> 
    </xsd:sequence> 
</xsd:complexType> 
</xsd:schema>" 

यह Xsd मॉड्यूल में प्रत्येक प्रकार के लिए थोड़ा कनवर्टर कार्यों डालकर काम करता है, और यह भी प्रकार के हैं, जैसे कि योग और उत्पाद प्रकार के संयोजन के लिए। इसमें सबसे अधिक जरूरतों को शामिल करना चाहिए। क्या Xsd मॉड्यूल प्रकार दिखाई देंगे:

(* xsd.fsi *) 

/// Just a string marked by the type of data whose XSD it holds. 
/// Implementation is private so that callers can't create any XSD 
/// they like. 
type 'a t 

/// Gives us the string representation of the XSD. 
val to_string : 'a t -> string 

/// Wraps an XSD encoding inside the <xsd:schema> tag pair. 
val root : 'a t -> 'a t 

// Primitive types. 

val int : int t 
val int64 : int64 t 
val string : string t 

/// Encode a two-field record's type (name and fields along with their 
/// types) as XSD. 
val record2 : string -> string * 'a1 t * string * 'a2 t -> 'a t 

(* xsd.fs *) 

type 'a t = { to_string : string } 

let to_string xsd = xsd.to_string 
let root xsd = 
    { to_string = 
     sprintf "<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"> 
    %s 
</xsd:schema>" xsd.to_string } 

let int = { to_string = "integer" } 
let int64 = { to_string = "long" } 
let string = { to_string = "string" } 

/// Helper for record fields. 
let element name typ = 
    sprintf "<xsd:element name=\"%s\" type=\"%s\"/>" name typ 

let record2 name (field1, xsd1, field2, xsd2) = 
    { to_string = 
     sprintf 
     "<xsd:complexType name=\"%s\"> 
    <xsd:sequence> 
    %s 
    %s 
    </xsd:sequence> 
</xsd:complexType>" 
     name 
     (element field1 xsd1.to_string) 
     (element field2 xsd2.to_string) } 

वैसे, यह क्रम प्रतिबिंब का उपयोग की तुलना में एक अपरिचित तकनीक है। लेकिन यह भी अधिक प्रकार के सुरक्षित है और आपको एन्कोडिंग पर नियंत्रण नियंत्रण प्रदान करता है। आपको शायद XSD के सभी को लागू करने की आवश्यकता नहीं है - आपको बस उन हिस्सों की आवश्यकता है जो आपके प्रकार वास्तव में उपयोग करते हैं।

0

यदि आप अपने कोड से किसी भी प्रकार का एक्सएसडी जेनरेट करना चाहते हैं, तो इस एफ # स्क्रिप्ट पर एक नज़र डालें। यह एफ # रिकॉर्ड प्रकार का एक्सएसडी उत्पन्न करता है। स्क्रिप्ट तीन .NET असेंबली का उपयोग करता है: System.Runtime.Serialization.dll, System.Runtime.Serialization.Xml, System.Xml

#r "System.Runtime.Serialization.dll" 
#r "System.Runtime.Serialization.Xml.dll" 
#r "System.Xml.dll" 

open System 
open System.IO 
open System.Linq 
open System.Text 
open System.Text.RegularExpressions 
open System.Xml 
open System.Runtime.Serialization 

type [<DataContract>] CommitInfo = { 
    [<field: DataMember(Name="id") >] 
    id: string 
    [<field: DataMember(Name="date") >] 
    date: DateTime 
    [<field: DataMember(Name="issueUrl") >] 
    issueUrl: string 
    [<field: DataMember(Name="issueId") >] 
    issueId: int 
    [<field: DataMember(Name="message") >] 
    message: string 
    [<field: DataMember(Name="url") >] 
    url: string 
} 

let getXmlWriter (stream: Stream) = 
    //let utf8noBOM = new UTF8Encoding(false) 
    let settings = new XmlWriterSettings() 
    settings.Indent <- true 
    settings.Encoding <- Encoding.UTF8 
    //settings.OmitXmlDeclaration <- true 
    XmlWriter.Create(stream, settings) 

let streamToString (stream: Stream) = 
    stream.Position <- int64 0 
    use sr = new StreamReader(stream) 
    sr.ReadToEnd() 

let getResultFromStream (streamWriter: Stream -> unit) = 
    use stream = new MemoryStream() 
    streamWriter stream 
    streamToString stream 

let exporter = XsdDataContractExporter() 
exporter.Export(typeof<CommitInfo array>) 
let schemas = exporter.Schemas.Schemas().Cast<Schema.XmlSchema>() |> Array.ofSeq 
let schema = schemas.[1] 

fun s -> s |> getXmlWriter |> schema.Write 
|> getResultFromStream 
|> printfn "%s" 
संबंधित मुद्दे

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