Neat Samples: F#, Freebase and DGML
Jomo Fisher – I recently posted about the freebase web service here. This sample reads biological classifications and renders them in DGML. The result is a huge graph, here’s a little piece of it:
Code Snippet
- // FreebaseDgml.fsx
- // Example of reading from freebase.com in F# using DataContract and JSON serializer and write the result
- // in .dgml format.
- // by Jomo Fisher
- #r "System.Runtime.Serialization"
- #r "System.ServiceModel.Web"
- #r "System.Web"
- #r "System.Xml"
- open System
- open System.IO
- open System.Net
- open System.Text
- open System.Web
- open System.Collections.Generic
- open System.Security.Authentication
- open System.Runtime.Serialization
- [<DataContract>]
- type Result<'TResult> = {
- [<field: DataMember(Name="code") >]
- Code:string
- [<field: DataMember(Name="result") >]
- Result:'TResult
- [<field: DataMember(Name="message") >]
- Message:string
- }
- [<DataContract>]
- type Classification = {
- [<field: DataMember(Name="name") >]
- Name:string
- [<field: DataMember(Name="higher_classification") >]
- HigherClassification:string
- [<field: DataMember(Name="lower_classifications") >]
- LowerClassifications:string array
- }
- let Query<'T>(query:string) : 'T =
- let query = query.Replace("'","\"")
- let queryUrl = sprintf "https://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
- let ser = Json.DataContractJsonSerializer(typeof<Result<'T>>)
- let result = ser.ReadObject(stream) :?> Result<'T>
- if result.Code<>"/api/status/ok" then
- raise (InvalidOperationException(result.Message))
- else
- result.Result
- let classifications = Query<Classification array>("[{'type':'/biology/organism_classification','name':null,'higher_classification':null,'lower_classifications':[]}]")
- let sb = StringBuilder()
- sb.Append("<DirectedGraph xmlns='https://schemas.microsoft.com/vs/2009/dgml'>\n") |> ignore
- sb.Append(" <Links>\n") |> ignore
- for classification in classifications do
- if classification.LowerClassifications<>null then
- for lower in classification.LowerClassifications do
- sb.AppendFormat(" <Link Source=\"{0}\" Target=\"{1}\"/>\n",classification.Name,lower) |> ignore
- sb.Append(" </Links>\n") |> ignore
- sb.Append("</DirectedGraph>\n") |> ignore
- printfn "%s" (sb.ToString()) // Paste the results of this into a .dgml file.
This posting is provided "AS IS" with no warranties, and confers no rights.