如何读取来自 T-SQL 的 xml 响应?

How can I read a xml Response from T-SQL?

我有这个存储过程来调用和读取来自 Web 服务的响应。我从存储过程调用 Web 服务。 当我尝试阅读回复时遇到问题。所以代码是这样的:

SET @Response=
    '
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <soap:Body>
            <RegisterUserResponse xmlns="http://tempuri.org/">
                <RegisterUserResult>DRnGXcT2gFTTxta4+ohnVx30Q1UL7N8gUqx0zpYMtMqmgwhkHmmXRWSoHu+Ghk0x</RegisterUserResult>
            </RegisterUserResponse>
        </soap:Body>
    </soap:Envelope>'

    declare @iXDoc int
    EXEC sp_xml_preparedocument @iXDoc OUTPUT, @Response

    select *
    from openxml(@iXDoc, '/Envelope/Body/RegisterUserresponse/RegisterUserResult',2)

我的结果是空的。如果我尝试更改

中的查询
select *
        from openxml(@iXDoc, '',2)

我得到了结果,但对我来说还不行。

您的 XML 有两个重要的名称空间; soap 在根元素中声明的命名空间和在 <RegisterUserResponse> 元素中声明的默认命名空间。因此,您需要将名称空间前缀映射作为参数传递给 sp_xml_preparedocument :

declare @nsmap varchar(200) = '<root xmlns:d="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"/>'
declare @iXDoc int
EXEC sp_xml_preparedocument @iXDoc OUTPUT, @Response, @nsmap

然后在 xpath 中正确使用映射的前缀:

select *
from openxml(@iXDoc, '/soap:Envelope/soap:Body/d:RegisterUserResponse/d:RegisterUserResult',2)

如果可能,在您使用的 SQL 服务器版本中,总是更喜欢使用本机 xquery 从 XML 获取数据的更简洁的方式,例如:

declare @Response varchar(max) = '
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <soap:Body>
            <RegisterUserResponse xmlns="http://tempuri.org/">
                <RegisterUserResult>DRnGXcT2gFTTxta4+ohnVx30Q1UL7N8gUqx0zpYMtMqmgwhkHmmXRWSoHu+Ghk0x</RegisterUserResult>
            </RegisterUserResponse>
        </soap:Body>
    </soap:Envelope>'

;WITH XMLNAMESPACES 
(
    DEFAULT 'http://tempuri.org/',
    'http://schemas.xmlsoap.org/soap/envelope/' as soap
)
SELECT CAST(@Response AS XML).value('(/soap:Envelope/soap:Body/RegisterUserResponse/RegisterUserResult)[1]', 'varchar(max)')
  as 'RegisterUserResult'

SQL Fiddle Demo