Neat Sample: F# and Bing API

Jomo Fisher – I recently posted an sample of calling the Freebase web service with F#. Here’s another F# web service sample. This one uses the Bing Phone API to do a query. This time the code uses Xml instead of JSON and XmlDocument instead of a DataContract deserializer. This is pretty much a straight transliteration of one of the Bing SDK samples.

 

Code Snippet

  1. // BingPhone.fsx
  2. // An example of using the a Bing web service API from F#
  3. // by Jomo Fisher
  4. open System.Net
  5. open System.Xml
  6.  
  7. let appId = "your app id goes here";
  8.  
  9. let BuildRequest() : HttpWebRequest  =
  10.     let requestString =
  11.         "https://api.bing.net/xml.aspx?"
  12.  
  13.             // Common request fields (required)
  14.             + "AppId=" + appId
  15.             + "&Query=microsoft offices"
  16.             + "&Sources=Phonebook"
  17.  
  18.             // Common request fields (optional)
  19.             + "&Version=2.0"
  20.             + "&Market=en-us"
  21.             + "&UILanguage=en"
  22.             + "&Latitude=47.603450"
  23.             + "&Longitude=-122.329696"
  24.             + "&Radius=10.0"
  25.  
  26.             // Phonebook-specific request fields (optional)
  27.             + "&Phonebook.Count=10"
  28.             + "&Phonebook.Offset=0"
  29.             + "&Phonebook.FileType=YP"
  30.             + "&Phonebook.SortBy=Distance";
  31.  
  32.     // Create and initialize the request.
  33.     downcast HttpWebRequest.Create(requestString)
  34.  
  35. let DisplayErrors(errors:XmlNodeList) =
  36.     // Iterate over the list of errors and display error details.
  37.     printfn "Errors:"
  38.     for error in errors do
  39.         for detail in error.ChildNodes do
  40.             printfn "%s: %s" detail.Name detail.InnerText
  41.  
  42. let DisplayResults( root:XmlNode, nsmgr:XmlNamespaceManager) =
  43.     // Add the Phonebook SourceType namespace to the namespace manager.
  44.     nsmgr.AddNamespace("pho", "https://schemas.microsoft.com/LiveSearch/2008/04/XML/phonebook")
  45.  
  46.     let phonebook = root.SelectSingleNode("./pho:Phonebook", nsmgr)
  47.     let results = phonebook.SelectNodes("./pho:Results/pho:PhonebookResult",nsmgr)
  48.  
  49.     let version = root.SelectSingleNode("./@Version", nsmgr).InnerText
  50.     let searchTerms = root.SelectSingleNode("./api:Query/api:SearchTerms",nsmgr).InnerText
  51.     let _,offset = System.Int32.TryParse(phonebook.SelectSingleNode("./pho:Offset", nsmgr).InnerText)
  52.     let _,total =  System.Int32.TryParse(phonebook.SelectSingleNode("./pho:Total", nsmgr).InnerText)
  53.  
  54.     // Display the results header.
  55.     printfn "Bing API Version %s" version
  56.     printfn "Phonebook results for %s" searchTerms
  57.     printfn "Displaying %d to %d of %d results" (offset + 1) (offset + results.Count) total
  58.  
  59.     // Display the Phonebook results.
  60.     let builder = System.Text.StringBuilder();
  61.     for result in results do
  62.         builder.Length <- 0
  63.         builder
  64.             .AppendLine(result.SelectSingleNode("./pho:Business", nsmgr).InnerText)
  65.             .AppendLine(result.SelectSingleNode("./pho:Address", nsmgr).InnerText)
  66.             .Append(result.SelectSingleNode("./pho:City", nsmgr).InnerText)
  67.             .Append(", ")|>ignore
  68.  
  69.         let stateOrProvince = result.SelectSingleNode("./pho:StateOrProvince", nsmgr).InnerText
  70.         builder
  71.             .AppendLine(stateOrProvince)
  72.             .AppendLine(result.SelectSingleNode("./pho:PhoneNumber", nsmgr).InnerText)
  73.             .Append("Average Rating: ")
  74.             .AppendLine(result.SelectSingleNode("./pho:UserRating", nsmgr).InnerText)|>ignore
  75.  
  76.         printfn "%s" (builder.ToString())
  77.  
  78. let DisplayResponse(response:HttpWebResponse) =
  79.     // Load the response into an XmlDocument.
  80.     let document = XmlDocument()
  81.     document.Load(response.GetResponseStream());
  82.  
  83.     // Add the default namespace to the namespace manager.
  84.     let nsmgr = XmlNamespaceManager(document.NameTable);
  85.     nsmgr.AddNamespace("api","https://schemas.microsoft.com/LiveSearch/2008/04/XML/element");
  86.  
  87.     let errors = document.DocumentElement.SelectNodes("./api:Errors/api:Error", nsmgr)
  88.  
  89.     if errors.Count > 0 then
  90.         // There are errors in the response. Display error details.
  91.         DisplayErrors(errors);
  92.     else
  93.         // There were no errors in the response. Display the
  94.         // Phonebook results.
  95.         DisplayResults(document.DocumentElement, nsmgr);
  96.  
  97.  
  98. let request = BuildRequest()
  99.  
  100. try
  101.     // Send the request; display the response.
  102.     let response = request.GetResponse()
  103.     DisplayResponse(downcast response)
  104. with ex ->
  105.     // An exception occurred while accessing the network.
  106.     printfn "%s" ex.Message

As before, let me know if there are other F# samples you’d like to see.

This posting is provided "AS IS" with no warranties, and confers no rights.