xpath получает много узлов одновременно - PullRequest
0 голосов
/ 21 ноября 2018

Я новичок в Xpath и не могу решить эту проблему в течение нескольких часов.Я получил xml-ответ от maps.googleapis.com/maps/api/geocode/xml?latlng=51,0, который содержит несколько «результатов», и каждый «результат» может содержать несколько «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 ") и подузлы (" long_name "," short_name ") определенных узлов" address_component "в нем.Пример вывода:

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>

Может кто-нибудь подсказать мне, как этого добиться, пожалуйста?

Например: vals toзахватить

1 Ответ

0 голосов
/ 22 ноября 2018

Исходя из того, что я могу понять из вашего вопроса, включая ваши комментарии, это то, что вы хотите?

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

Он получает первый result дочерний узел GeocodeResponse узла (который имеет дочерний элемент)статус = ОК)С узлом result, имеющим потомка long_name (который имеет значение 'Hazel Grove').

EDIT

Пожалуйста, используйте вместо этого 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
...