【问题标题】:Parsing an XML response given by Bing API in SQL server 2014在 SQL Server 2014 中解析 Bing API 给出的 XML 响应
【发布时间】:2019-06-26 07:30:25
【问题描述】:

我正在使用 SQL Server 2014,我正在调用 Bing 距离矩阵 API 来获取 2 个经纬度坐标之间的距离,并且我能够接收到 API 的 XML 输出。问题是我无法解析 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 响应位于此链接中: https://docs.microsoft.com/en-us/bingmaps/rest-services/examples/distance-matrix-example

【问题讨论】:

    标签: sql-server xml bing-api


    【解决方案1】:

    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)');
    

    【讨论】:

      【解决方案2】:

      从我的测试中可以看出,解析器不喜欢第 3 行中的版权字符

      试试这个:

      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 似乎对我有用

      【讨论】:

      • 该错误是因为 utf-8 中的字符 © 在表示为 varchar 时应编码为 ©
      猜你喜欢
      • 1970-01-01
      • 2019-12-05
      • 1970-01-01
      • 2017-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-18
      • 1970-01-01
      相关资源
      最近更新 更多