如何读取来自 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'
我有这个存储过程来调用和读取来自 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'