기본적으로 JSON과 형식이 지정된 xml 모두에 직렬화를 처리 할 단일 구조가 있어야합니다. 레코드는 json과의 직렬화를 위해 잘 작동했습니다. 그러나 XmlSerializer에는 매개 변수없는 구속자가 필요합니다. 나는이 구조물들에 대한 클래스 객체를 구축하는 연습을 거치고 싶지 않습니다 (원칙 만). 매개 변수없는 생성자를 레코드 (아마도 wioth 문 또는 뭔가)에 가져 오는 지름길이있을 수 있기를 바랬습니다. 나는 행동을 취할 수 없다 - 공동체에있는 누구라도 행운을 빕니다.F # 레코드에 생성자를 추가 하시겠습니까?
module JSONExample
open System
open System.IO
open System.Net
open System.Text
open System.Web
open System.Xml
open System.Security.Authentication
open System.Runtime.Serialization //add assemnbly reference System.Runtime.Serialization System.Xml
open System.Xml.Serialization
open System.Collections.Generic
[<DataContract>]
type ChemicalElementRecord = {
[<XmlAttribute("name")>]
[<field: DataMember(Name="name") >]
Name:string
[<XmlAttribute("name")>]
[<field: DataMember(Name="boiling_point") >]
BoilingPoint:string
[<XmlAttribute("atomic-mass")>]
[<field: DataMember(Name="atomic_mass") >]
AtomicMass:string
}
[<XmlRoot("freebase")>]
[<DataContract>]
type FreebaseResultRecord = {
[<XmlAttribute("code")>]
[<field: DataMember(Name="code") >]
Code:string
[<XmlArrayAttribute("results")>]
[<XmlArrayItem(typeof<ChemicalElementRecord>, ElementName = "chemical-element")>]
[<field: DataMember(Name="result") >]
Result: ChemicalElementRecord array
[<XmlElement("message")>]
[<field: DataMember(Name="message") >]
Message:string
}
let getJsonFromWeb() =
let query = "[{'type':'/chemistry/chemical_element','name':null,'boiling_point':null,'atomic_mass':null}]"
let query = query.Replace("'","\"")
let queryUrl = sprintf "http://api.freebase.com/api/service/mqlread?query=%s" "{\"query\":"+query+"}"
let request : HttpWebRequest = downcast WebRequest.Create(queryUrl)
request.Method <- "GET"
request.ContentType <- "application/x-www-form-urlencoded"
let response = request.GetResponse()
let result =
try
use reader = new StreamReader(response.GetResponseStream())
reader.ReadToEnd();
finally
response.Close()
let data = Encoding.Unicode.GetBytes(result);
let stream = new MemoryStream()
stream.Write(data, 0, data.Length);
stream.Position <- 0L
stream
let test =
// get some JSON from the web
let stream = getJsonFromWeb()
// convert the stream of JSON into an F# Record
let JsonSerializer = Json.DataContractJsonSerializer(typeof<FreebaseResultRecord>)
let result: FreebaseResultRecord = downcast JsonSerializer.ReadObject(stream)
// save the Records to disk as JSON
use fs = new FileStream(@"C:\temp\freebase.json", FileMode.Create)
JsonSerializer.WriteObject(fs,result)
fs.Close()
// save the Records to disk as System Controlled XML
let xmlSerializer = DataContractSerializer(typeof<FreebaseResultRecord>);
use fs = new FileStream(@"C:\temp\freebase.xml", FileMode.Create)
xmlSerializer.WriteObject(fs,result)
fs.Close()
use fs = new FileStream(@"C:\temp\freebase-pretty.xml", FileMode.Create)
let xmlSerializer = XmlSerializer(typeof<FreebaseResultRecord>)
xmlSerializer.Serialize(fs,result)
fs.Close()
ignore(test)
DataContractSerializer에 대한 XML의 출력 형식을 제어 할 수 있습니까? 나는 원래 시도해 보니 너무 기분이 좋지 않았다. 당신이 볼 수 있듯이 나는 디스크에 3 개의 serializaiton을 가지고 있고 secnod는 그 포맷을 사용한다. – akaphenom
실제 문제는 네임 스페이스와 i.Nil 속성을 추가 한 것입니다 ... – akaphenom
알겠습니다. 빠른 웹 검색은 아니오를 제안합니다. 예를 들어 http://stackoverflow.com/questions/1953984/is-there-a-way-to-make-datacontractserializer-output-cleaner-xml – Brian