Introdução
Este artigo tem sua origem em uma pergunta postada no Fórum TechNet Brasil do SQL Server - Ler envelope do SOAP e irá fornecer à você um problema sobre o consumo de um pacote XML estruturado através do protocolo SOAP, recebido através de um Web Service para consultar seus dados em T-SQL.Esta é uma das possíveis soluções relacionadas para este problema, se você conhece outras opções em T-SQL que atendam à necessidade do problema proposto, fique à vontade para acrescentar seu conteúdo neste artigo.
Problema
Durante minha leitura nos Threads do Fórum de SQL, encontrei à seguinte pergunta.A pergunta era: "Estou consumindo um Web Service via T-SQL e preciso ler o envelope de retorno dele. O retorno esta assim:"
<soap:Envelopexmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="http://tempuri.org/"xmlns:types="http://tempuri.org/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Bodysoap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<IntegraPJResponse>
<IntegraPJResultxsi:type="xsd:string">
<retornosucesso="true">
<id>7d8444e6-4d78-e311-895e-00155d0b0b36</id>
</retorno>
</IntegraPJResult>
</IntegraPJResponse>
</soap:Body>
</soap:Envelope>
O XML indicado pelo inquiridor é um Envelope de retorno válido obtido através de um Web Service. Esta validação pode ser executada através de qualquer ferramenta de XML Parser. Neste caso, estou utilizando o
Microsoft XML Parser (KB 324460).
Neste caso, o foco do problema está isolado no consumo do envelope do SOAP, já que o recebimento através do Web Service foi realizado com sucesso. Mesmo não sendo claro, o inquiridor quer obter exatamente a
chave GUID indicada dentro do nó
retorno. Exatamente o valor do nó id.
Causas
Quando recebemos um XML de um Web Service ele pode ter apenas dois tipos de retorno: com sucesso (onde o XML possui um formato definido) ou com falha onde o XML retorna apenas o cabeçalho do Web Service e uma mensagem de erro que pode ser retornada por um método do Web Service ou por problema na estrutura do XML. Neste caso, o consumidor destes dados deve estar preparado para receber o XML em ambos os casos.O problema deste Thread no Fórum era mais simples, apesar de que o inquiridor não tinha certeza se estava recebendo a resposta do seu Web Service corretamente.
A validação é simples, já que basta o XML ser válido e possuir os devidos namespaces para identificação do objeto e seus devidos nós.
Solução
Precisamos identificar quais são os nós que correspondem à resposta do Web Service e seu efetivo resultado.No caso do XML encaminhado pelo inquiridor, é simples já que todo conteúdo está dentro do nó Body, e este nó possui apenas um nó filho Response o que é comum neste tipo de retorno. Já no caso do nó Result o SOAP pode ter mais de um nó (o que não é muito comum), mas não é este o caso já que possui apenas uma resposta.
Dentro do nó Result está o conteúdo que realmente interessa ao inquiridor. O XML criado efetivamente para retornar pelo Web Service e ser consumido pelo banco de dados.
Então, temos à seguinte ordem:
- nó Response: IntegraPJResponse
- nó Result: IntegraPJResponse
- nó de Retorno (conteúdo esperado): retorno\id
Os critérios que fazem toda diferença para tornar esta solução em uma consulta simples e prática é identificar exatamente onamespace recebido no XML do Web Service e mapear os nós até o valor ou atributo desejado.
Neste caso, declaramos o namespace soap (padrão deste tipo de solução), indicando à sua referência de validação, neste caso o endereço Web http://schemas.xmlsoap.org/soap/envelope/.
O mapeamento do XML pode ser um pouco trabalhoso, dependendo da quantidade de nós indicada no XML e o que realmente precisamos consumir.
Para o inquiridor, o número GUID é o suficiente, então fica mais fácil. Mapeamos os nós na consulta até o pai do nó id (onde está o valor que desejamos) que é o nó retorno e fazemos à referência para localizar à informação em T-SQL. Os objetos para executar esta tarefas são nomeados pelo desenvolvedor e referenciam o conteúdo da propriedades do XML, neste caso, chamei de RETORNO a declaração do namespace para que o Parser XML do SQL Server possa identificar os nós Envelope e Body, e chamei de VALOR o caminho até o nó retorno, para obter o nó id.
Na instrução SELECT é necessário informar qual propriedade do nó desejamos. Como precisamos do valor, declaramos à funcão valuee seu conteúdo deve ser o nó id e sua conversão para um tipo de dado válido no SQL Server. Para demostração, definir como varchar.
Vamos executar à isntrução para verificar o resultado. Segue abaixo o script T-SQL desta solução:
DECLARE@xxml
SET@x='<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:tns="http://tempuri.org/" xmlns:types="http://tempuri.org/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<IntegraPJResponse>
<IntegraPJResult xsi:type="xsd:string">
<retorno sucesso="true">
<id>7d8444e6-4d78-e311-895e-00155d0b0b36</id>
</retorno>
</IntegraPJResult>
</IntegraPJResponse>
</soap:Body>
</soap:Envelope>'
SELECTRETORNO.VALOR.value('id[1]','varchar(100)')ASVALOR_ID
FROM@x.nodes(
'declare namespace soap="http://schemas.xmlsoap.org/soap/envelope/";
/soap:Envelope/soap:Body/IntegraPJResponse/IntegraPJResult/retorno')asRETORNO(VALOR)
GO
O resultado é exibido após a execução desta instrução no SSMS. Veja o resultado na imagem abaixo:
Veja Também
Leia alguns tópicos relacionados ao assunto:- XML Parser (w3schools)
- Especificação SOAP (w3C)
- Formatos de mensagem SOAP padrão especificados com o WSDL
- Introducing XML Serialization
- Visão geral dos XML Web Services Nativos
- Estrutura de mensagens de solicitação SOAP
- Estrutura de mensagens de resposta SOAP
- Diretrizes e limitações dos XML Web Services Nativos
- Como instalar o Microsoft XML Parser e o Microsoft XML Core Services (MSXML)
- MSDN Data Access Blog - Introduction to SQL 2005 Native XML Web Services (SOAP)