解析 SQL 服务器 2014 中 Bing API 给出的 XML 响应
Parsing an XML response given by Bing API in SQL server 2014
我正在使用 SQL 服务器 2014,我正在调用 Bing 距离矩阵 API 来获取 2 个经纬度坐标之间的距离,我能够收到一个
XML 来自 API 的输出。问题是我无法解析 XML 以检索 TravelDistance 标记中的值。我如何解析来自 API?
的响应
我试过使用内置的 OPENXML 函数。我收到 NULL 响应。
我将响应转换为 XML 并尝试:
Set @XML=CAST(@response AS XML)
Set @distance=@XML.value('(Response/ResourceSets/ResourceSet/Resources/Resource/Result/Distance/TravelDistance)[1]', 'varchar(20)')
导致 NULL 响应。
但是选择@XML 会给我完整的回复
示例 XML 响应在此 link 中:
https://docs.microsoft.com/en-us/bingmaps/rest-services/examples/distance-matrix-example
XML 使用名称空间,因此您也需要这样做。
with xmlnamespaces(default 'http://schemas.microsoft.com/search/local/ws/rest/v1')
select @XML.value('(Response/ResourceSets/ResourceSet/Resources/Resource/Results/Distance/TravelDistance)[1]', 'varchar(20)');
并且您在 XQuery 表达式中有错字。
declare @XML xml = '<?xml version="1.0" encoding="utf-8"?>
<Response xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/search/local/ws/rest/v1">
<Copyright>Copyright © 2017 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.</Copyright>
<BrandLogoUri>http://dev.virtualearth.net/Branding/logo_powered_by.png</BrandLogoUri>
<StatusCode>200</StatusCode>
<StatusDescription>OK</StatusDescription>
<AuthenticationResultCode>ValidCredentials</AuthenticationResultCode>
<TraceId>9eaa7048e9cc457c804c15bac083d8b7|BN20220145|7.7.0.0|</TraceId>
<ResourceSets>
<ResourceSet>
<EstimatedTotal>1</EstimatedTotal>
<Resources>
<Resource xsi:type="DistanceMatrix">
<Origins>
<Coordinate>
<Latitude>47.6044</Latitude>
<Longitude>-122.3345</Longitude>
</Coordinate>
<Coordinate>
<Latitude>47.6731</Latitude>
<Longitude>-122.1185</Longitude>
</Coordinate>
<Coordinate>
<Latitude>47.6149</Latitude>
<Longitude>-122.1936</Longitude>
</Coordinate>
</Origins>
<Destinations>
<Coordinate>
<Latitude>45.5347</Latitude>
<Longitude>-122.6231</Longitude>
</Coordinate>
<Coordinate>
<Latitude>47.4747</Latitude>
<Longitude>-122.2057</Longitude>
</Coordinate>
</Destinations>
<Results>
<Distance>
<DepartureTime xsi:nil="true" />
<OriginIndex>0</OriginIndex>
<DestinationIndex>0</DestinationIndex>
<TravelDistance>281.261777777778</TravelDistance>
<TravelDuration>9560.7</TravelDuration>
<TotalWalkDuration>0</TotalWalkDuration>
</Distance>
<Distance>
<DepartureTime xsi:nil="true" />
<OriginIndex>0</OriginIndex>
<DestinationIndex>1</DestinationIndex>
<TravelDistance>23.284</TravelDistance>
<TravelDuration>931.5</TravelDuration>
<TotalWalkDuration>0</TotalWalkDuration>
</Distance>
<Distance>
<DepartureTime xsi:nil="true" />
<OriginIndex>1</OriginIndex>
<DestinationIndex>0</DestinationIndex>
<TravelDistance>296.074722222222</TravelDistance>
<TravelDuration>10203.1</TravelDuration>
<TotalWalkDuration>0</TotalWalkDuration>
</Distance>
<Distance>
<DepartureTime xsi:nil="true" />
<OriginIndex>1</OriginIndex>
<DestinationIndex>1</DestinationIndex>
<TravelDistance>28.4669444444444</TravelDistance>
<TravelDuration>1155.6</TravelDuration>
<TotalWalkDuration>0</TotalWalkDuration>
</Distance>
<Distance>
<DepartureTime xsi:nil="true" />
<OriginIndex>2</OriginIndex>
<DestinationIndex>0</DestinationIndex>
<TravelDistance>285.752194444444</TravelDistance>
<TravelDuration>9818.4</TravelDuration>
<TotalWalkDuration>0</TotalWalkDuration>
</Distance>
<Distance>
<DepartureTime xsi:nil="true" />
<OriginIndex>2</OriginIndex>
<DestinationIndex>1</DestinationIndex>
<TravelDistance>18.1444166666667</TravelDistance>
<TravelDuration>770.9</TravelDuration>
<TotalWalkDuration>0</TotalWalkDuration>
</Distance>
</Results>
</Resource>
</Resources>
</ResourceSet>
</ResourceSets>
</Response>';
with xmlnamespaces(default 'http://schemas.microsoft.com/search/local/ws/rest/v1')
select @XML.value('(Response/ResourceSets/ResourceSet/Resources/Resource/Results/Distance/TravelDistance)[1]', 'varchar(20)');
据我在测试中得知,解析器不喜欢第 3 行中的 Copyright 字符
试试这个:
declare @xml xml
set @xml = convert(xml,
replace('<?xml version="1.0" encoding="utf-8"?>
<Response xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/search/local/ws/rest/v1">
<Copyright>Copyright © 2017 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.</Copyright>
<BrandLogoUri>http://dev.virtualearth.net/Branding/logo_powered_by.png</BrandLogoUri>
<StatusCode>200</StatusCode>
<StatusDescription>OK</StatusDescription>
<AuthenticationResultCode>ValidCredentials</AuthenticationResultCode>
<TraceId>9eaa7048e9cc457c804c15bac083d8b7|BN20220145|7.7.0.0|</TraceId>
<ResourceSets>
<ResourceSet>
<EstimatedTotal>1</EstimatedTotal>
<Resources>
<Resource xsi:type="DistanceMatrix">
<Origins>
<Coordinate>
<Latitude>47.6044</Latitude>
<Longitude>-122.3345</Longitude>
</Coordinate>
<Coordinate>
<Latitude>47.6731</Latitude>
<Longitude>-122.1185</Longitude>
</Coordinate>
<Coordinate>
<Latitude>47.6149</Latitude>
<Longitude>-122.1936</Longitude>
</Coordinate>
</Origins>
<Destinations>
<Coordinate>
<Latitude>45.5347</Latitude>
<Longitude>-122.6231</Longitude>
</Coordinate>
<Coordinate>
<Latitude>47.4747</Latitude>
<Longitude>-122.2057</Longitude>
</Coordinate>
</Destinations>
<Results>
<Distance>
<DepartureTime xsi:nil="true" />
<OriginIndex>0</OriginIndex>
<DestinationIndex>0</DestinationIndex>
<TravelDistance>281.261777777778</TravelDistance>
<TravelDuration>9560.7</TravelDuration>
<TotalWalkDuration>0</TotalWalkDuration>
</Distance>
<Distance>
<DepartureTime xsi:nil="true" />
<OriginIndex>0</OriginIndex>
<DestinationIndex>1</DestinationIndex>
<TravelDistance>23.284</TravelDistance>
<TravelDuration>931.5</TravelDuration>
<TotalWalkDuration>0</TotalWalkDuration>
</Distance>
<Distance>
<DepartureTime xsi:nil="true" />
<OriginIndex>1</OriginIndex>
<DestinationIndex>0</DestinationIndex>
<TravelDistance>296.074722222222</TravelDistance>
<TravelDuration>10203.1</TravelDuration>
<TotalWalkDuration>0</TotalWalkDuration>
</Distance>
<Distance>
<DepartureTime xsi:nil="true" />
<OriginIndex>1</OriginIndex>
<DestinationIndex>1</DestinationIndex>
<TravelDistance>28.4669444444444</TravelDistance>
<TravelDuration>1155.6</TravelDuration>
<TotalWalkDuration>0</TotalWalkDuration>
</Distance>
<Distance>
<DepartureTime xsi:nil="true" />
<OriginIndex>2</OriginIndex>
<DestinationIndex>0</DestinationIndex>
<TravelDistance>285.752194444444</TravelDistance>
<TravelDuration>9818.4</TravelDuration>
<TotalWalkDuration>0</TotalWalkDuration>
</Distance>
<Distance>
<DepartureTime xsi:nil="true" />
<OriginIndex>2</OriginIndex>
<DestinationIndex>1</DestinationIndex>
<TravelDistance>18.1444166666667</TravelDistance>
<TravelDuration>770.9</TravelDuration>
<TotalWalkDuration>0</TotalWalkDuration>
</Distance>
</Results>
</Resource>
</Resources>
</ResourceSet>
</ResourceSets>
</Response>','©',''))
select @xml
尝试剥离它,然后转换为 XML 似乎对我有用
我正在使用 SQL 服务器 2014,我正在调用 Bing 距离矩阵 API 来获取 2 个经纬度坐标之间的距离,我能够收到一个 XML 来自 API 的输出。问题是我无法解析 XML 以检索 TravelDistance 标记中的值。我如何解析来自 API?
的响应我试过使用内置的 OPENXML 函数。我收到 NULL 响应。
我将响应转换为 XML 并尝试:
Set @XML=CAST(@response AS XML)
Set @distance=@XML.value('(Response/ResourceSets/ResourceSet/Resources/Resource/Result/Distance/TravelDistance)[1]', 'varchar(20)')
导致 NULL 响应。
但是选择@XML 会给我完整的回复
示例 XML 响应在此 link 中: https://docs.microsoft.com/en-us/bingmaps/rest-services/examples/distance-matrix-example
XML 使用名称空间,因此您也需要这样做。
with xmlnamespaces(default 'http://schemas.microsoft.com/search/local/ws/rest/v1')
select @XML.value('(Response/ResourceSets/ResourceSet/Resources/Resource/Results/Distance/TravelDistance)[1]', 'varchar(20)');
并且您在 XQuery 表达式中有错字。
declare @XML xml = '<?xml version="1.0" encoding="utf-8"?>
<Response xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/search/local/ws/rest/v1">
<Copyright>Copyright © 2017 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.</Copyright>
<BrandLogoUri>http://dev.virtualearth.net/Branding/logo_powered_by.png</BrandLogoUri>
<StatusCode>200</StatusCode>
<StatusDescription>OK</StatusDescription>
<AuthenticationResultCode>ValidCredentials</AuthenticationResultCode>
<TraceId>9eaa7048e9cc457c804c15bac083d8b7|BN20220145|7.7.0.0|</TraceId>
<ResourceSets>
<ResourceSet>
<EstimatedTotal>1</EstimatedTotal>
<Resources>
<Resource xsi:type="DistanceMatrix">
<Origins>
<Coordinate>
<Latitude>47.6044</Latitude>
<Longitude>-122.3345</Longitude>
</Coordinate>
<Coordinate>
<Latitude>47.6731</Latitude>
<Longitude>-122.1185</Longitude>
</Coordinate>
<Coordinate>
<Latitude>47.6149</Latitude>
<Longitude>-122.1936</Longitude>
</Coordinate>
</Origins>
<Destinations>
<Coordinate>
<Latitude>45.5347</Latitude>
<Longitude>-122.6231</Longitude>
</Coordinate>
<Coordinate>
<Latitude>47.4747</Latitude>
<Longitude>-122.2057</Longitude>
</Coordinate>
</Destinations>
<Results>
<Distance>
<DepartureTime xsi:nil="true" />
<OriginIndex>0</OriginIndex>
<DestinationIndex>0</DestinationIndex>
<TravelDistance>281.261777777778</TravelDistance>
<TravelDuration>9560.7</TravelDuration>
<TotalWalkDuration>0</TotalWalkDuration>
</Distance>
<Distance>
<DepartureTime xsi:nil="true" />
<OriginIndex>0</OriginIndex>
<DestinationIndex>1</DestinationIndex>
<TravelDistance>23.284</TravelDistance>
<TravelDuration>931.5</TravelDuration>
<TotalWalkDuration>0</TotalWalkDuration>
</Distance>
<Distance>
<DepartureTime xsi:nil="true" />
<OriginIndex>1</OriginIndex>
<DestinationIndex>0</DestinationIndex>
<TravelDistance>296.074722222222</TravelDistance>
<TravelDuration>10203.1</TravelDuration>
<TotalWalkDuration>0</TotalWalkDuration>
</Distance>
<Distance>
<DepartureTime xsi:nil="true" />
<OriginIndex>1</OriginIndex>
<DestinationIndex>1</DestinationIndex>
<TravelDistance>28.4669444444444</TravelDistance>
<TravelDuration>1155.6</TravelDuration>
<TotalWalkDuration>0</TotalWalkDuration>
</Distance>
<Distance>
<DepartureTime xsi:nil="true" />
<OriginIndex>2</OriginIndex>
<DestinationIndex>0</DestinationIndex>
<TravelDistance>285.752194444444</TravelDistance>
<TravelDuration>9818.4</TravelDuration>
<TotalWalkDuration>0</TotalWalkDuration>
</Distance>
<Distance>
<DepartureTime xsi:nil="true" />
<OriginIndex>2</OriginIndex>
<DestinationIndex>1</DestinationIndex>
<TravelDistance>18.1444166666667</TravelDistance>
<TravelDuration>770.9</TravelDuration>
<TotalWalkDuration>0</TotalWalkDuration>
</Distance>
</Results>
</Resource>
</Resources>
</ResourceSet>
</ResourceSets>
</Response>';
with xmlnamespaces(default 'http://schemas.microsoft.com/search/local/ws/rest/v1')
select @XML.value('(Response/ResourceSets/ResourceSet/Resources/Resource/Results/Distance/TravelDistance)[1]', 'varchar(20)');
据我在测试中得知,解析器不喜欢第 3 行中的 Copyright 字符
试试这个:
declare @xml xml
set @xml = convert(xml,
replace('<?xml version="1.0" encoding="utf-8"?>
<Response xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/search/local/ws/rest/v1">
<Copyright>Copyright © 2017 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.</Copyright>
<BrandLogoUri>http://dev.virtualearth.net/Branding/logo_powered_by.png</BrandLogoUri>
<StatusCode>200</StatusCode>
<StatusDescription>OK</StatusDescription>
<AuthenticationResultCode>ValidCredentials</AuthenticationResultCode>
<TraceId>9eaa7048e9cc457c804c15bac083d8b7|BN20220145|7.7.0.0|</TraceId>
<ResourceSets>
<ResourceSet>
<EstimatedTotal>1</EstimatedTotal>
<Resources>
<Resource xsi:type="DistanceMatrix">
<Origins>
<Coordinate>
<Latitude>47.6044</Latitude>
<Longitude>-122.3345</Longitude>
</Coordinate>
<Coordinate>
<Latitude>47.6731</Latitude>
<Longitude>-122.1185</Longitude>
</Coordinate>
<Coordinate>
<Latitude>47.6149</Latitude>
<Longitude>-122.1936</Longitude>
</Coordinate>
</Origins>
<Destinations>
<Coordinate>
<Latitude>45.5347</Latitude>
<Longitude>-122.6231</Longitude>
</Coordinate>
<Coordinate>
<Latitude>47.4747</Latitude>
<Longitude>-122.2057</Longitude>
</Coordinate>
</Destinations>
<Results>
<Distance>
<DepartureTime xsi:nil="true" />
<OriginIndex>0</OriginIndex>
<DestinationIndex>0</DestinationIndex>
<TravelDistance>281.261777777778</TravelDistance>
<TravelDuration>9560.7</TravelDuration>
<TotalWalkDuration>0</TotalWalkDuration>
</Distance>
<Distance>
<DepartureTime xsi:nil="true" />
<OriginIndex>0</OriginIndex>
<DestinationIndex>1</DestinationIndex>
<TravelDistance>23.284</TravelDistance>
<TravelDuration>931.5</TravelDuration>
<TotalWalkDuration>0</TotalWalkDuration>
</Distance>
<Distance>
<DepartureTime xsi:nil="true" />
<OriginIndex>1</OriginIndex>
<DestinationIndex>0</DestinationIndex>
<TravelDistance>296.074722222222</TravelDistance>
<TravelDuration>10203.1</TravelDuration>
<TotalWalkDuration>0</TotalWalkDuration>
</Distance>
<Distance>
<DepartureTime xsi:nil="true" />
<OriginIndex>1</OriginIndex>
<DestinationIndex>1</DestinationIndex>
<TravelDistance>28.4669444444444</TravelDistance>
<TravelDuration>1155.6</TravelDuration>
<TotalWalkDuration>0</TotalWalkDuration>
</Distance>
<Distance>
<DepartureTime xsi:nil="true" />
<OriginIndex>2</OriginIndex>
<DestinationIndex>0</DestinationIndex>
<TravelDistance>285.752194444444</TravelDistance>
<TravelDuration>9818.4</TravelDuration>
<TotalWalkDuration>0</TotalWalkDuration>
</Distance>
<Distance>
<DepartureTime xsi:nil="true" />
<OriginIndex>2</OriginIndex>
<DestinationIndex>1</DestinationIndex>
<TravelDistance>18.1444166666667</TravelDistance>
<TravelDuration>770.9</TravelDuration>
<TotalWalkDuration>0</TotalWalkDuration>
</Distance>
</Results>
</Resource>
</Resources>
</ResourceSet>
</ResourceSets>
</Response>','©',''))
select @xml
尝试剥离它,然后转换为 XML 似乎对我有用