我正在将一些xml映射到一个案例类,它工作正常,但我感觉我的命令性的眼罩让我眼花缭乱,找到了更好的功能解决方案.任何人都可以建议一个比这更好的方法:
def buildAddress(geocodeResponse: NodeSeq) : Address = { val addressNodes = geocodeResponse \\ "address_component" var street = " " var town = "" var suburb = "" var province = "" var country = "" var postalCode = "" addressNodes.foreach {node => val typestring = (node \ "type").head.text if ("street_number" == typestring) { street = (node \ "long_name").text + street } else if ("route" == typestring) { street = street + (node \ "long_name").text } else if ("locality" == typestring) { town = (node \ "long_name").text } else if ("sublocality" == typestring) { suburb = (node \ "long_name").text } else if ("administrative_area_level_1" == typestring) { province = (node \ "long_name").text } else if ("country" == typestring) { country = (node \ "long_name").text } else if ("postal_code" == typestring) { town = (node \ "long_name").text } } Address(street,suburb,town,province,country,postalCode) }
在这种情况下,使用dispatch从Google地理编码API中检索xml.
import dispatch._ def lookupAddress(lat: Double,long: Double): Address = { val position = lat.toString + "," + long.toString val req = url("http://maps.googleapis.com/maps/api/geocode/xml") <<? Map("latlng" -> position,"sensor" -> "true") Http(req </> { nodes => buildAddress(nodes) }) }
xml结果如下所示:
<GeocodeResponse> <status>OK</status> <result> <type>street_address</type> <formatted_address>3 Louw St,Stellenbosch 7600,South Africa</formatted_address> <address_component> <long_name>3</long_name> <short_name>3</short_name> <type>street_number</type> </address_component> <address_component> <long_name>Louw St</long_name> <short_name>Louw St</short_name> <type>route</type> </address_component> <address_component> <long_name>Stellenbosch Central</long_name> <short_name>Stellenbosch Central</short_name> <type>sublocality</type> <type>political</type> </address_component> <address_component> <long_name>Stellenbosch</long_name> <short_name>Stellenbosch</short_name> <type>locality</type> <type>political</type> </address_component> <address_component> <long_name>Stellenbosch</long_name> <short_name>Stellenbosch</short_name> <type>administrative_area_level_3</type> <type>political</type> </address_component> <address_component> <long_name>Brede River DC</long_name> <short_name>Brede River DC</short_name> <type>administrative_area_level_2</type> <type>political</type> </address_component> <address_component> <long_name>Western Cape</long_name> <short_name>WC</short_name> <type>administrative_area_level_1</type> <type>political</type> </address_component> <address_component> <long_name>South Africa</long_name> <short_name>ZA</short_name> <type>country</type> <type>political</type> </address_component> <address_component> <long_name>7600</long_name> <short_name>7600</short_name> <type>postal_code</type> </address_component> <geometry> <location> <lat>-33.9403990</lat> <lng>18.8610090</lng> </location> <location_type>ROOFTOP</location_type> <viewport> <southwest> <lat>-33.9435466</lat> <lng>18.8578614</lng> </southwest> <northeast> <lat>-33.9372514</lat> <lng>18.8641566</lng> </northeast> </viewport> </geometry> </result> <result> <type>sublocality</type> <type>political</type> <formatted_address>Stellenbosch Central,Stellenbosch,South Africa</formatted_address> <address_component> <long_name>Stellenbosch Central</long_name> <short_name>Stellenbosch Central</short_name> <type>sublocality</type> <type>political</type> </address_component> <address_component> <long_name>Stellenbosch</long_name> <short_name>Stellenbosch</short_name> <type>locality</type> <type>political</type> </address_component> <address_component> <long_name>Stellenbosch</long_name> <short_name>Stellenbosch</short_name> <type>administrative_area_level_3</type> <type>political</type> </address_component> <address_component> <long_name>Brede River DC</long_name> <short_name>Brede River DC</short_name> <type>administrative_area_level_2</type> <type>political</type> </address_component> <address_component> <long_name>Western Cape</long_name> <short_name>WC</short_name> <type>administrative_area_level_1</type> <type>political</type> </address_component> <address_component> <long_name>South Africa</long_name> <short_name>ZA</short_name> <type>country</type> <type>political</type> </address_component> <geometry> <location> <lat>-33.9354048</lat> <lng>18.8640607</lng> </location> <location_type>APPROXIMATE</location_type> <viewport> <southwest> <lat>-33.9437180</lat> <lng>18.8449199</lng> </southwest> <northeast> <lat>-33.9230960</lat> <lng>18.8778929</lng> </northeast> </viewport> <bounds> <southwest> <lat>-33.9437180</lat> <lng>18.8449199</lng> </southwest> <northeast> <lat>-33.9230960</lat> <lng>18.8778929</lng> </northeast> </bounds> </geometry> </result> <result> <type>postal_code</type> <formatted_address>7599,South Africa</formatted_address> <address_component> <long_name>7599</long_name> <short_name>7599</short_name> <type>postal_code</type> </address_component> <address_component> <long_name>Brede River DC</long_name> <short_name>Brede River DC</short_name> <type>administrative_area_level_2</type> <type>political</type> </address_component> <address_component> <long_name>Western Cape</long_name> <short_name>WC</short_name> <type>administrative_area_level_1</type> <type>political</type> </address_component> <address_component> <long_name>South Africa</long_name> <short_name>ZA</short_name> <type>country</type> <type>political</type> </address_component> <geometry> <location> <lat>-33.9300286</lat> <lng>18.8640607</lng> </location> <location_type>APPROXIMATE</location_type> <viewport> <southwest> <lat>-33.9693080</lat> <lng>18.8019200</lng> </southwest> <northeast> <lat>-33.8700550</lat> <lng>18.9232900</lng> </northeast> </viewport> <bounds> <southwest> <lat>-33.9693080</lat> <lng>18.8019200</lng> </southwest> <northeast> <lat>-33.8700550</lat> <lng>18.9232900</lng> </northeast> </bounds> </geometry> </result> <result> <type>locality</type> <type>political</type> <formatted_address>Stellenbosch,South Africa</formatted_address> <address_component> <long_name>Stellenbosch</long_name> <short_name>Stellenbosch</short_name> <type>locality</type> <type>political</type> </address_component> <address_component> <long_name>Stellenbosch</long_name> <short_name>Stellenbosch</short_name> <type>administrative_area_level_3</type> <type>political</type> </address_component> <address_component> <long_name>Brede River DC</long_name> <short_name>Brede River DC</short_name> <type>administrative_area_level_2</type> <type>political</type> </address_component> <address_component> <long_name>Western Cape</long_name> <short_name>WC</short_name> <type>administrative_area_level_1</type> <type>political</type> </address_component> <address_component> <long_name>South Africa</long_name> <short_name>ZA</short_name> <type>country</type> <type>political</type> </address_component> <geometry> <location> <lat>-33.9366667</lat> <lng>18.8613889</lng> </location> <location_type>APPROXIMATE</location_type> <viewport> <southwest> <lat>-34.0150869</lat> <lng>18.7658819</lng> </southwest> <northeast> <lat>-33.8782960</lat> <lng>18.9232900</lng> </northeast> </viewport> <bounds> <southwest> <lat>-34.0150869</lat> <lng>18.7658819</lng> </southwest> <northeast> <lat>-33.8782960</lat> <lng>18.9232900</lng> </northeast> </bounds> </geometry> </result> <result> <type>postal_code</type> <formatted_address>7600,South Africa</formatted_address> <address_component> <long_name>7600</long_name> <short_name>7600</short_name> <type>postal_code</type> </address_component> <address_component> <long_name>Western Cape</long_name> <short_name>WC</short_name> <type>administrative_area_level_1</type> <type>political</type> </address_component> <address_component> <long_name>South Africa</long_name> <short_name>ZA</short_name> <type>country</type> <type>political</type> </address_component> <geometry/> </result> <result> <type>administrative_area_level_3</type> <type>political</type> <formatted_address>Stellenbosch,South Africa</formatted_address> <address_component> <long_name>Stellenbosch</long_name> <short_name>Stellenbosch</short_name> <type>administrative_area_level_3</type> <type>political</type> </address_component> <address_component> <long_name>Brede River DC</long_name> <short_name>Brede River DC</short_name> <type>administrative_area_level_2</type> <type>political</type> </address_component> <address_component> <long_name>Western Cape</long_name> <short_name>WC</short_name> <type>administrative_area_level_1</type> <type>political</type> </address_component> <address_component> <long_name>South Africa</long_name> <short_name>ZA</short_name> <type>country</type> <type>political</type> </address_component> <geometry> <location> <lat>-33.9405478</lat> <lng>18.9502232</lng> </location> <location_type>APPROXIMATE</location_type> <viewport> <southwest> <lat>-34.0633899</lat> <lng>18.7083300</lng> </southwest> <northeast> <lat>-33.7933599</lat> <lng>19.2438000</lng> </northeast> </viewport> <bounds> <southwest> <lat>-34.0633899</lat> <lng>18.7083300</lng> </southwest> <northeast> <lat>-33.7933599</lat> <lng>19.2438000</lng> </northeast> </bounds> </geometry> </result> <result> <type>administrative_area_level_2</type> <type>political</type> <formatted_address>Brede River DC,South Africa</formatted_address> <address_component> <long_name>Brede River DC</long_name> <short_name>Brede River DC</short_name> <type>administrative_area_level_2</type> <type>political</type> </address_component> <address_component> <long_name>Western Cape</long_name> <short_name>WC</short_name> <type>administrative_area_level_1</type> <type>political</type> </address_component> <address_component> <long_name>South Africa</long_name> <short_name>ZA</short_name> <type>country</type> <type>political</type> </address_component> <geometry> <location> <lat>-33.4220698</lat> <lng>19.7591675</lng> </location> <location_type>APPROXIMATE</location_type> <viewport> <southwest> <lat>-34.1172599</lat> <lng>18.7083299</lng> </southwest> <northeast> <lat>-32.1844899</lat> <lng>21.0103399</lng> </northeast> </viewport> <bounds> <southwest> <lat>-34.1172599</lat> <lng>18.7083299</lng> </southwest> <northeast> <lat>-32.1844899</lat> <lng>21.0103399</lng> </northeast> </bounds> </geometry> </result> <result> <type>administrative_area_level_1</type> <type>political</type> <formatted_address>Western Cape,South Africa</formatted_address> <address_component> <long_name>Western Cape</long_name> <short_name>WC</short_name> <type>administrative_area_level_1</type> <type>political</type> </address_component> <address_component> <long_name>South Africa</long_name> <short_name>ZA</short_name> <type>country</type> <type>political</type> </address_component> <geometry> <location> <lat>-33.2277918</lat> <lng>21.8568586</lng> </location> <location_type>APPROXIMATE</location_type> <viewport> <southwest> <lat>-34.8330538</lat> <lng>17.7575638</lng> </southwest> <northeast> <lat>-30.4302599</lat> <lng>24.2224100</lng> </northeast> </viewport> <bounds> <southwest> <lat>-34.8330538</lat> <lng>17.7575638</lng> </southwest> <northeast> <lat>-30.4302599</lat> <lng>24.2224100</lng> </northeast> </bounds> </geometry> </result> <result> <type>country</type> <type>political</type> <formatted_address>South Africa</formatted_address> <address_component> <long_name>South Africa</long_name> <short_name>ZA</short_name> <type>country</type> <type>political</type> </address_component> <geometry> <location> <lat>-30.5594820</lat> <lng>22.9375060</lng> </location> <location_type>APPROXIMATE</location_type> <viewport> <southwest> <lat>-34.9670000</lat> <lng>16.2817000</lng> </southwest> <northeast> <lat>-22.1253869</lat> <lng>33.0469000</lng> </northeast> </viewport> <bounds> <southwest> <lat>-34.9670000</lat> <lng>16.2817000</lng> </southwest> <northeast> <lat>-22.1253869</lat> <lng>33.0469000</lng> </northeast> </bounds> </geometry> </result> </GeocodeResponse>
解决方法
除非你得到某种反思,否则你真的没有太多可以让它变得更好.看起来你可以改善你的属性匹配,做这样的事情,以帮助它的纯粹苦差事:
def buildAddress(geocodeResponse: NodeSeq) : Address = { def getComponent(component: String): String = { val longNames = for { addressComponent <- geocodeResponse \\ "address_component" componentType <- addressComponent \ "type" if componentType.text == component } yield addressComponent \ "long_name" longNames.head.text } implicit def toC(s: String) = new { def c = getComponent(s) } implicit val map = Map( 'street -> ("route".c + "street_number".c),'town -> "locality".c,'suburb -> "sublocality".c,'province -> "administrative_area_level_1".c,'country -> "country".c,'postalCode -> "postal_code".c ) Address('street,'suburb,'town,'province,'country,'postalCode) }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。