우리는 미래에 프로젝트에 F #을 활용하려고하고 있으며 F # 유형의 .xsd 스키마를 자동으로 생성 할 수 있기를 원합니다.F # 유형에 대해 .xsd를 생성하는 방법이 있습니까?
웹 검색은 .xsd에서 유형을 생성하는 데 많은 답을 표시하지만 그 반대의 경우는 아닙니다.
아무도이 작업을 수행하는 방법을 알고 있습니까?
우리는 미래에 프로젝트에 F #을 활용하려고하고 있으며 F # 유형의 .xsd 스키마를 자동으로 생성 할 수 있기를 원합니다.F # 유형에 대해 .xsd를 생성하는 방법이 있습니까?
웹 검색은 .xsd에서 유형을 생성하는 데 많은 답을 표시하지만 그 반대의 경우는 아닙니다.
아무도이 작업을 수행하는 방법을 알고 있습니까?
그런 의미는 실제로 의미하는 바에 달려 있습니다.
의미 : "어떻게하면 DLL에서 XSD를 생성합니까?" 그래도 svcutil을 사용하면 간단하게 처리 할 수 있습니다 ... 다른 조건이 충족되었지만 수행 할 수있는 종류가 있다고 가정하면
다음 명령은 어셈블리의 서비스 계약 및 관련 유형에 대한 메타 데이터 문서를 생성합니다.
svcutil myAssembly.dll
https://msdn.microsoft.com/en-us/library/aa347733(v=vs.110).aspx
xsd.exe도 가지 거의 동일 할 수 있어야합니다. 임 비록 여기에 어떤 조건 하에서,하지만 워드 프로세서 svcutil 너무 "엄격한"되지 않습니다.
다음 명령은 어셈블리 myAssembly.dll의 모든 유형에 대해 XML 스키마를 생성하고이를 현재 디렉토리에 schema0.xsd로 저장합니다.
xsd myAssembly.dll
https://msdn.microsoft.com/en-us/library/x6c1kb0s(v=vs.110).aspx
당신이 의미하는 경우에 당신이 (내 지식)의 운이 친절 "파일 * 주어진 .fs에서 XSD를 생성합니다."
내가 틀릴 수도 있지만, 충분히 잘 작동하는 경우 XSD를 기반으로하는 F # 유형 공급자를 사용하는 것보다 더 실용적인 방법으로 어떻게 수행 할 수 있는지 보지 못합니다. 그러나 그때, 나는 하나가 있는지 확신하지 못한다.
FSharp.Data.Xsd 유형 공급자를 사용해보십시오. 소스에서 XSD를 문자열로 지정하거나 소스 외부의 XSD 파일을 참조하여 지정할 수 있습니다. 원하는 XSD를 생성 할 수 없습니다.
문제는 필자가 준비 할 필요가없는 타협을하지 않는 한 F # 유형만으로는 XSD의 모습을 구체적으로 지정할 수 없다는 것입니다.
매핑을 제어하기 위해 F #에서 특정 유형을 만들겠습니까? 그런 유형을 사용하지 않아도 "F #을 활용할 것"이라고 생각하지 않습니다.
코드 속성이나 다른 메타 데이터를 사용 하시겠습니까? 이 경우 F # 형식 대신 XSD를 편집하지 않는 것이 좋습니까?
일대일 매핑을 암시하는 규칙을 간단하게 만들겠습니까? 작동하지만 원하는 XSD 및 XML을 생성하지 못할 수도 있습니다. 그것은 너무 장황해질 수 있습니다.
XSD를 생성해야합니다. 반면에 유형 제공자를 사용하여 XSD에서 F # 유형을 생성하면 생성 된 유형을 즉시 사용할 수 있습니다.훨씬 더 실용적이고 즐겁지 않습니까?
나는 'typeclasses'를 사용하여 이것을 접근 할 것입니다. 빠른 예제 (REPL에서). type Person = { id : int64; name : string}
과 같이 Person
유형이 있다고 가정합니다. 그러면 :
Xsd
모듈의 종류마다 작은 계산기 기능을 바꾸어 동작
> ("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.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의 모든을 구현할 필요는 없습니다. 유형을 실제로 사용하기 만하면됩니다.
코드에서 모든 유형의 XSD를 생성하려면이 F # 스크립트를 살펴보십시오. F # 레코드 유형의 XSD를 생성합니다. Script는 세 가지 .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"
답변 해 주셔서 감사합니다. 우리는 F #의 간결함을 이용하기 위해 F # 유형 자체에 대한 .xsd를 생성하고 기본 CLI 유형을 생성하지 않을 것입니다. 우리는 .dll을 통해 접근 방식을 시도해 보입니다. 그러나 더 직접적인 매핑이 가능하기를 희망합니다. –