Convertendo XML em JSON com XSLT

Uma situação bem comum no uso de APIs é conseguir adaptar um backend legado que muitas vezes é um SOAP para uma estrutura RESTFUL. Sendo assim é necessário a conversão de algum XML para JSON. Isso pode ser feito através do interceptor XML to JSON, porém nem sempre o resultado sai como o esperado devido a simplicidade da conversão. Para obter uma conversão mais eficaz podemos utilizar uma forma personalizada de conversão com o interceptor de XSLT.

 

Exemplo de XML de retorno do backend

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"/>
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>Server validation error</faultstring>
<detail>
<ns2:WsError xmlns:ns2="http://all.wsdl.cms.com/">
<faults>
<responseCode>-2</responseCode>
<responseDesc>notificationId: Id Aviso de viagem inválido</responseDesc>
</faults>
</ns2:WsError>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>

 

Exemplo de XSLT para conversão de XML em JSON

//Estrutura básica para que o XSLT funcione
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output encoding="UTF-8" indent="yes" media-type="application/json" method="text"/>
<xsl:template match="/">


//Daqui para baixo entrará a estrutura do XML para conversão
//xsl:if é uma tag condicional, ou seja, caso a condição imposta na abertura da tag seja atendida, o conteúdo da tag será incluído na saída.
<xsl:if test="(count(*:Envelope/*:Body/*:Fault/detail/*:WsError) gt 1)">[</xsl:if>


//xsl:for-each é um laço, sendo assim para cada elemento encontrado, definido no select, ele executará as linhas abaixo.
OBS: É necessário descer todos os níveis do XML, separando-os por /
<xsl:for-each select="*:Envelope/*:Body/*:Fault/detail/*:WsError">
<xsl:if test="(count(faults) gt 1)">[</xsl:if>
<xsl:for-each select="faults">


//xsl:text faz com que o conteúdo dessa tag seja printado na resposta como texto puro
<xsl:text>{</xsl:text>


//xsl:value-of seleciona o conteúdo da tag presente no XML e printa na resposta
<xsl:text>"code":</xsl:text>"<xsl:value-of select="responseCode"/>"<xsl:text>,</xsl:text>
<xsl:text>"descricao":</xsl:text>"<xsl:value-of select="responseDesc"/>"
<xsl:text>}</xsl:text>


//Aqui buscamos por qualquer outra tag que contenha :faults para adicionar a virgula separadora se necessário
<xsl:if test="./following-sibling::faults">
<xsl:text>,</xsl:text>
</xsl:if>


//Fechamos o laço da tag faults
</xsl:for-each>


//Fechamos o Array se necessário
<xsl:if test="(count(faults) gt 1)">]</xsl:if>
<xsl:if test="./following-sibling::*">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:if test="(count(*:Envelope/*:Body/*:Fault/detail/*:WsError) gt 1)">]</xsl:if>


//Fechamos a estrutura básica
</xsl:template>
</xsl:stylesheet>

 

Resultado da conversão

{

"code":"-2",

"descricao":"notificationId: Id Aviso de viagem inválido"

}

Tem mais dúvidas? Envie uma solicitação

Comentários

Powered by Zendesk