我有这个Store Procedure来调用和读取来自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)
我有结果,但对我来说不合适。
答案 0 :(得分:1)
您的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 Server版本中,总是更喜欢使用本机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 强>