2017-06-11 18 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

谢谢。不确定我是否真的通过这样做获得了很多,但值得了解。再次感谢您的帮助。 –