xpath一次获取多个节点

时间:2018-11-21 07:35:45

标签: google-maps xpath xml-parsing

我是Xpath的新手,现在已经有几个小时无法解决了。 我收到了maps.googleapis.com/maps/api/geocode/xml?latlng=51,0的xml响应 其中包含多个“结果”,每个“结果”可能包含多个“ address_component”。 响应是在特定的编中解析的,并且不能使用诸如

的串联
/GeocodeResponse[1]/status[text()='OK'] | /GeocodeResponse[1]/result[1]/type | /GeocodeResponse[1]/result[1]/address_component[1]...

并且只能通过一个请求来完成

/GeocodeResponse[1]/[self::status[text()='OK'] or self::result[1]/type or self::result[1]/address_component[1]] 

但是此路径返回所有“结果”,而我只需要第一个和其中的节点(“ type”,“ formatted_address”)以及某个“ address_component”的子节点(“ long_name”,“ short_name”) ”中的节点。 输出示例:

GeocodeResponse[1]/status
GeocodeResponse[1]/result[1]/type[1]
GeocodeResponse[1]/result[1]/formatted_address[1]
GeocodeResponse[1]/result[1]/address_component/short_name - where "address_component" contains "types" with text ('street_number', 'route', 'locality', 'administrative_area_level_1', 'postal_code')

源xml响应如下:

`<GeocodeResponse>
<status>OK</status>
<result>
<type>establishment</type>
<type>point_of_interest</type>
<formatted_address>2 Hazel Grove, Radcliffe, Uckfield M26 1DD, UK</formatted_address>
<address_component>
<long_name>2</long_name>
<short_name>2</short_name>
<type>street_number</type>
</address_component>
<address_component>
<long_name>Hazel Grove</long_name>
<short_name>Hazel Grove</short_name>
<type>route</type>
</address_component>
<address_component>
<long_name>Radcliffe</long_name>
<short_name>Radcliffe</short_name>
<type>locality</type>
<type>political</type>
</address_component>
<address_component>
<long_name>Uckfield</long_name>
<short_name>Uckfield</short_name>
<type>postal_town</type>
</address_component>
<address_component>
<long_name>East Sussex</long_name>
<short_name>East Sussex</short_name>
<type>administrative_area_level_2</type>
<type>political</type>
</address_component>
<address_component>
<long_name>England</long_name>
<short_name>England</short_name>
<type>administrative_area_level_1</type>
<type>political</type>
</address_component>
<address_component>
<long_name>United Kingdom</long_name>
<short_name>GB</short_name>
<type>country</type>
<type>political</type>
</address_component>
<address_component>
<long_name>M26 1DD</long_name>
<short_name>M26 1DD</short_name>
<type>postal_code</type>
</address_component>
<geometry>
<location>
<lat>51.0000000</lat>
<lng>0.0000000</lng>
</location>
<location_type>ROOFTOP</location_type>
<viewport>
<southwest>
<lat>50.9986510</lat>
<lng>-0.0013490</lng>
</southwest>
<northeast>
<lat>51.0013490</lat>
<lng>0.0013490</lng>
</northeast>
</viewport>
</geometry>
<place_id>ChIJ_8dXPfiLdUgR9wQihY2gsgk</place_id>
<plus_code>
<global_code>9F322222+22</global_code>
<compound_code>2222+22 Sheffield Green, United Kingdom</compound_code>
</plus_code>
</result>
<result>
<type>postal_code</type>
<formatted_address>Uckfield TN22 3QS, UK</formatted_address>
<address_component>
<long_name>TN22 3QS</long_name>
<short_name>TN22 3QS</short_name>
<type>postal_code</type>
</address_component>
<address_component>
<long_name>Uckfield</long_name>
<short_name>Uckfield</short_name>
<type>postal_town</type>
</address_component>
<address_component>
<long_name>East Sussex</long_name>
<short_name>East Sussex</short_name>
<type>administrative_area_level_2</type>
<type>political</type>
</address_component>
<address_component>
<long_name>England</long_name>
<short_name>England</short_name>
<type>administrative_area_level_1</type>
<type>political</type>
</address_component>
<address_component>
<long_name>United Kingdom</long_name>
<short_name>GB</short_name>
<type>country</type>
<type>political</type>
</address_component>
<geometry>
<location>
<lat>50.9973315</lat>
<lng>0.0079172</lng>
</location>
<location_type>APPROXIMATE</location_type>
<viewport>
<southwest>
<lat>50.9959291</lat>
<lng>-0.0003802</lng>
</southwest>
<northeast>
<lat>51.0023266</lat>
<lng>0.0087596</lng>
</northeast>
</viewport>
<bounds>
<southwest>
<lat>50.9959291</lat>
<lng>-0.0003802</lng>
</southwest>
<northeast>
<lat>51.0023266</lat>
<lng>0.0087596</lng>
</northeast>
</bounds>
</geometry>
<place_id>ChIJqWgEbhpg30cRL6VL5HVT3NI</place_id>
</result>
<result>...</result>
<result>...</result>
<result>...</result>
<result>...</result>
<result>...</result>
<result>...</result>
<result>...</result>
<plus_code>
<global_code>9F322222+22</global_code>
<compound_code>2222+22 Sheffield Green, UK</compound_code>
</plus_code>
</GeocodeResponse>

有人可以建议我如何实现这一目标吗?

e.g.: vals to grab

1 个答案:

答案 0 :(得分:0)

根据我对您的问题(包括您的评论)的理解,这是您想要的吗?

//GeocodeResponse[status='OK']/result[address_component/long_name[.='Hazel Grove']][1]

它获得result节点的第一个GeocodeResponse子节点(其子状态= OK)。 result节点具有后代long_name(其值为'Hazel Grove')。

编辑

请改用该xpath:

//GeocodeResponse[status='OK']/result[address_component/long_name[.='Hazel Grove']][1]/(preceding-sibling::status|type[1]|formatted_address[1]|address_component/short_name[../type='street_number' or ../type='route' or ../type='locality' or ../type='administrative_area_level_1' or ../type='postal_code'])

根据我对XML的测试,它会输出

OK
establishment
2 Hazel Grove, Radcliffe, Uckfield M26 1DD, UK
2
Hazel Grove
Radcliffe
England
M26 1DD