2017-06-11 52 views
3

我正在觀看「Why you should use F#」上的第9頻道視頻,並對將維基百科中的數據拉出是多麼容易的事情留下了深刻的印象。例如,他發現,羅列出來誰博士的不同外觀下面的代碼...如何從F#JsonProvider的URL中讀取JSON

[<Literal>] 
let url = @"https://en.wikipedia.org/wiki/Doctor_Who" 
type DoctorWhoData = HtmlProvider<url> 

let data = DoctorWhoData.GetSample() 
let app = data.Tables.``Changes of appearance``.Rows 

由於他打字,他有智能感知的最後一行,發生的猜測找到數據。

我最近有要求從Google Maps API提取一些數據。例如,下面的URL中提取數據爲英國郵政編碼SW1A 1AA(白金漢宮的情況下,任何有興趣!)...

http://maps.google.com/maps/api/geocode/json?address=sw1a+1aa+uk

鑑於該數據僅僅是JSON,我想這應該是平等容易從F#中獲取信息。但是,我試圖獲取經緯度時被卡住了。

我開始了與以下...

type GoogleData = JsonProvider<"http://maps.google.com/maps/api/geocode/json?address=sw1a+1aa+uk"> 

...但隨後就卡住試圖提取數據。 json包含一個包含一個條目的數組。其中包含一個geometry節點,其中包含一個location節點,該節點包含這兩個值。在僞代碼,我沒有料想到會做這樣的事情......

let lat = GoogleData.GetSample().[0].geometry.location.lat 

...但是,這並不工作。我嘗試了沒有GetSample(),但沒有得到更多。 Intellisense向我展示了一些與Json完全不匹配的東西... enter image description here

任何人都能夠告訴我哪裏出錯了?我如何查找數據?更重要的是,我如何獲得Intellisense來幫助我?我在C#中設法做到了這一點,但是由於我必須使用動態對象,所以沒有得到Intellisense,所以它非常難找。根據我在視頻中看到的內容,我希望在這裏獲得Intellisense。

回答

3

JSON響應包含2個頂級對象resultsstatus

{ 
    "results" : [ 
     { 
     "address_components" : [ 
      { 
       "long_name" : "SW1A 1AA", 
       "short_name" : "SW1A 1AA", 
       "types" : [ "postal_code" ] 
    //snip 
    ], 
    "status" : "OK" 
} 

lat和長是results下,所以你需要遵循下來從.GetSample()

let lat = GoogleData.GetSample().Results.[0].Geometry.Location.Lat 

使用其它數據比樣本數據使用Load功能:

let honley = GoogleData.Load "http://maps.google.com/maps/api/geocode/json?address=honley+uk" 
let honley_latlong = honley.Results.[0].Geometry.Location 

//{ 
// "lat": 53.602267, 
// "lng": -1.794173 
//} 
printfn "%A" honley_latlong 
+0

謝謝爲此,我沒有發現那個地位也處於頂級水平!有沒有一種既簡單又經濟的方法,比如'let(lat,lng)= ???',而不是整個線路的兩倍? –

+2

你可以定義一個輔助函數'let ll2tp(ll:GoogleData.Northeast)=(ll.Lat,ll.Lng)'then'let(lat,lng)= honley.Results。[0] .Geometry.Location |> ll2tp' – DaveShaw

+0

謝謝。不確定我是否真的通過這樣做獲得了很多,但值得了解。再次感謝您的幫助。 –