DEV Community

Silvair L. Soares
Silvair L. Soares

Posted on • Updated on

Validando o schema de arquivos XML com .Net e C#

Embora muitas pessoas possam torcer o nariz ao ouvirem termos como: Webservices, SOAP, XML, schema, XSD, WSDL, etc. São tecnologias que teremos que lidar em algum momento da nossa vida profissional.

Protocolos e padrões mais leves como REST, gRPC, GraphQL, etc estão cada vez mais se popularizando, mas existem grandes projetos (sem previsão de migração), consolidados que utilizam o protocolo SOAP para troca de informações entre sistemas.

No Brasil, dois grandes exemplos são a Nota Fiscal Eletrônica - NF-e e o Web Service de Rastreamento dos Correios.

O que vamos aprender neste artigo?

1 - Entender os fundamentos do protocolo SOAP;

2 - Criar um serviço genérico para validar qualquer arquivo XML, com diferentes schemas;

3 - Criar uma API REST em .Net para fazer a validação de arquivos XML;

1. O protocolo SOAP

Se existe um requisito comum, para a maioria das aplicações corporativas, é a integração entre diferentes sistemas. Nenhum software é (ou não deveria ser) uma ilha!

Alt Text

Se este for o seu caso, inevitavelmente em algum momento você precisará consumir algum serviço remoto, implementado por terceiros, durante o ciclo de vida operacional do seu sistema.

O protocolo SOAP - Simple Object Access Protocol (em português, Protocolo Simples de Acesso à Objeto) possibilita que esta tarefa seja executada de forma bastante eficiente.

SOAP utiliza o protocolo HTTP para transportar os dados. E devido ao fato de utilizar um protocolo padrão, permite que sistemas construídos com diferentes linguagens de programação e sendo executados em diferentes sistemas operacionais, troquem informações de forma transparente.

Além disso, permite que o produtor destes serviços remotos, defina o formato da entrada de dados que será aceito, utilizando para isto os XML Schema - XML Schema Definition (em português, Definição de Esquema XML).

São arquivos com a extensão .xsd, com os seguintes tipos de conteúdo:

<?xml version="1.0" encoding="utf-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:complexType name="TEndereco">
        <xsd:sequence>
            <xsd:element name="logradouro" type="xsd:string"/>
            <xsd:element name="complemento" type="xsd:string"/>
            <xsd:element name="bairro" type="xsd:string"/>
            <xsd:element name="CEP">
                <xsd:simpleType>
                    <xsd:restriction base="xsd:string">
                        <xsd:maxLength value = "9"/>
                        <xsd:minLength value = "9"/>
                    </xsd:restriction>
                </xsd:simpleType>
            </xsd:element>
        </xsd:sequence>
    </xsd:complexType>
</xsd:schema>
Enter fullscreen mode Exit fullscreen mode


No exemplo acima, foi definido uma entrada de endereços, chamada de TEndereco, contendo os campos: Logradouro, Numero, Complemento, Bairro e CEP, cada um com a sua respectiva regra de preenchimento. Através deste modelo, poderemos utilizar o tipo TEndereco em outros tipos de dados:

<?xml version="1.0" encoding="utf-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:include schemaLocation="TEndereco.xsd"/>
    <xsd:element name="pessoa">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="nome">
                    <xsd:simpleType>
                        <xsd:restriction base="xsd:string">
                            <xsd:maxLength value = "20"/>
                            <xsd:minLength value = "2"/>
                        </xsd:restriction>
                    </xsd:simpleType>
                </xsd:element>
                <xsd:element name="sobrenome">
                    <xsd:simpleType>
                        <xsd:restriction base="xsd:string">
                            <xsd:maxLength value = "20"/>
                            <xsd:minLength value = "2"/>
                        </xsd:restriction>
                    </xsd:simpleType>
                </xsd:element>
                <xsd:element name="endereco" minOccurs="1" maxOccurs="1" type="TEndereco"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>
Enter fullscreen mode Exit fullscreen mode

No exemplo acima, o tipo TEndereco foi utilizado no tipo TPessoa. Desta forma, é possível definir todas as regras do tipo de entrada aceito pelo webservice SOAP.

Para quem trabalha com orientação a objetos, os schemas seriam as classes, já os arquivos XML que transportam os dados, seriam uma instância desta classe.

Esta foi apenas uma pequena introdução ao protocolo SOAP, como não é objetivo deste artigo aprofundar neste tema, deixo aqui a fonte oficial de informações, para quem pretende entender de forma mais ampla, este vasto conteúdo:
https://www.w3.org/TR/soap/

2. Criando um serviço genérico para validar qualquer schema de diferentes tipos de XML

2.1. Ambiente necessário

Visual Studio Code (https://code.visualstudio.com/Download)
.Net 5.0 SDK (https://dotnet.microsoft.com/download/dotnet/thank-you/sdk-5.0.400-windows-x64-installer)

Vamos criar uma API simples, que receberá uma string que representa um arquivo XML validará o schema, e caso econtre alguma inconsistência, retornará uma mensagem detalhando todos os problemas encontrados.

Para a criação da WEB API, após a instalação do .Net 5.0 SDK, temos disponível uma poderosa ferramenta de linha de comando que nos ajudará inclusive com a criação do projeto.

Abra um diretório qualquer do seu computador, clique na barra de endereços, digite o comando CMD e tecle ENTER.

Alt Text

Ao fazer isto, o prompt de comando do Windows, abrirá o respectivo diretório automaticamente:

Alt Text

Digite o comando dotnet new webapi --name web.api.xml.schema.validation e tecle ENTER.

Alt Text

Após alguns segundos, teremos um projeto do tipo WEB API, criado e totalmente funcional.

Para acessá-lo no Visual Studio Code, navegue para o diretório do projeto no prompt de comando, digite code . e tecle e ENTER.

Alt Text

A tela do Visual Studio Code será aberta automaticamente, com o projeto previamente criado, já carregado:

Alt Text

Na primeira execução, o Visual Studio Code identificará a linguagem na qual o projeto está sendo desenvolvido e perguntará se deseja incluir a extensão para o C#, permita que ele faça a instalação, clicando no botão Install.

Para executar o projeto de teste, basta acessar o terminal do Visual Studio Code (CTRL + ‘) e digitar o comando: dotnet run.

Alt Text

A partir deste momento, basta acessar o endereço: https://localhost:5001/swagger no browser para ver a API sendo executada.

Alt Text

É incrível como é fácil criar e executar uma API no .Net né!

A seguir, criaremos um serviço injetável (injeção de dependência) que será utilizando no controller responsável por receber e validar o arquivo xml.

Crie o diretório Services na raiz do projeto, com os seguintes subdiretórios: ServiceInterfaces e Services.
Crie o arquivo IXMLValidationService.cs no diretório \Services\XMLValidation\ServiceInterfaces, com o seguinte conteúdo:

namespace web.api.xml.schema.validation.Services.InterfacesServicos
{
    public interface IXMLValidationService
    {        
        string XMLValidate(string XML);
    }
}
Enter fullscreen mode Exit fullscreen mode

Alt Text

Agora vamos criar uma classe que implementará o método XMLValidate definido na interface IXMLValidationService:

Crie o arquivo XMLValidationService.cs no diretório \Services\XMLValidation\Services, com o seguinte conteúdo:

using web.api.xml.schema.validation.Services.InterfacesServicos;

namespace web.api.xml.schema.validation.Services.Servicos
{
    public class XMLValidationService: IXMLValidationService
    {        

    }
}
Enter fullscreen mode Exit fullscreen mode

Neste momento, o Visual Studio Code exibirá um erro, pois não estamos ainda, implementando o XMLValidate definido na interface IXMLValidationService:

Alt Text

Para resolver este problema, posicione o mouse sobre o ícone da lâmpada amarela no início da linha 5 e clique na opção Implementar a interface:

Alt Text

A assinatura do método será criada automaticamente:

using web.api.xml.schema.validation.Services.InterfacesServicos;

namespace web.api.xml.schema.validation.Services.Servicos
{
    public class XMLValidationService : IXMLValidationService
    {
        public string XMLValidate(string XML)
        {
            throw new System.NotImplementedException();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Agora vamos dar início ao processo de validação do schema de fato.
Para isto, crie o subdiretório Schemas dentro do diretório \Services\XMLValidation.

Crie no diretório \Schemas os seguintes arquivos com seus respectivos conteúdos:

Arquivo: TEndereco.xsd
Conteúdo:

<?xml version="1.0" encoding="utf-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:complexType name="TEndereco">
        <xsd:sequence>
            <xsd:element name="logradouro" type="xsd:string"/>
            <xsd:element name="complemento" type="xsd:string"/>
            <xsd:element name="bairro" type="xsd:string"/>
            <xsd:element name="CEP">
                <xsd:simpleType>
                    <xsd:restriction base="xsd:string">
                        <xsd:maxLength value="9"/>
                        <xsd:minLength value="9"/>
                    </xsd:restriction>
                </xsd:simpleType>
            </xsd:element>
        </xsd:sequence>
    </xsd:complexType>
</xsd:schema>
Enter fullscreen mode Exit fullscreen mode

Arquivo: TPessoa.xsd
Conteúdo:

<?xml version="1.0" encoding="utf-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:include schemaLocation="TEndereco.xsd"/>
    <xsd:element name="pessoa">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="nome">
                    <xsd:simpleType>
                        <xsd:restriction base="xsd:string">
                            <xsd:maxLength value = "20"/>
                            <xsd:minLength value = "2"/>
                        </xsd:restriction>
                    </xsd:simpleType>
                </xsd:element>
                <xsd:element name="sobrenome">
                    <xsd:simpleType>
                        <xsd:restriction base="xsd:string">
                            <xsd:maxLength value = "20"/>
                            <xsd:minLength value = "2"/>
                        </xsd:restriction>
                    </xsd:simpleType>
                </xsd:element>
                <xsd:element name="endereco" minOccurs="1" maxOccurs="1" type="TEndereco"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>
Enter fullscreen mode Exit fullscreen mode

Estes arquivos são o schemas que validarão o conteúdo do arquivo xml recebido pela nossa WEB API.

O nosso método XMLValidate, contém um parâmetro do tipo string que será utilizada para criar um objeto do tipo System.Xml.XmlDocument.

Faça a seguinte modificação no método XMLValidate da classe XMLValidationService:

using System.Xml;
using web.api.xml.schema.validation.Services.InterfacesServicos;

namespace web.api.xml.schema.validation.Services.Servicos
{
    public class XMLValidationService : IXMLValidationService
    {
        public string XMLValidate(string XML)
        {
            XmlDocument document = new XmlDocument();            
            try
            {
                document.Load(XML);
            }
            catch (System.Exception ex)
            {                
                throw new System.Exception("Houve um erro ao gerar um documento XML com os dados recebidos. " + ex.Message);
            }

            return "";      
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Com isto, teremos um serviço que recebe uma string que representa um documento XML, tenta instanciar um XmlDocument e retorna uma exceção, caso o XML esteja com uma má formação.

Lembre-se, o que validaremos é um schema do XML e para isto, o conteúdo XML deverá no mínimo ser um XML bem formado.

Para criar o mecanismo de validação, utilizaremos o Validate(ValidationEventHandler validationEventHandler) do namespace System.Xml.XmlDocument.

Portanto, faça as seguintes modificações na classe XMLValidationService:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using System.Xml.Schema;
using web.api.xml.schema.validation.Services.InterfacesServicos;

namespace web.api.xml.schema.validation.Services.Servicos
{
    public class XMLValidationService : IXMLValidationService
    {
        private static readonly ICollection<string> falhas = new List<String>();

        public string XMLValidate(string XML)
        {
            XmlDocument document = new XmlDocument();
            try
            {
                document.LoadXml(XML);
                string falhas = ValidarXmlPessoa(document);

                if (falhas.Count() > 0)
                    return falhas;
                else
                    return "Arquivo validado com sucesso!";

            }
            catch (Exception ex)
            {
                throw new Exception("Houve um erro ao gerar um documento XML com os dados recebidos. " + ex.Message);
            }
        }

        /// <summary>
        /// Executa a validação de schema do XML do tipo "TPessoa", com base nos arquivos .xsd
        /// </summary>
        private string ValidarXmlPessoa(XmlDocument dados)
        {
            string retorno = "";
            // Inclui os schemas XSD para validação do documento do tipo "TPessoa" e suas dependências
            ICollection<string> XSDFiles = new List<String>();
            try
            {                
                XSDFiles.Add(@"Services\XMLValidation\Schemas\TPessoa.xsd");
                XSDFiles.Add(@"Services\XMLValidation\Schemas\TEndereco.xsd");
            }
            catch (Exception ex)
            {
                throw ex;
            }

            // Aciona o método genérico de validações de schemas, mas que neste contexto, estará validando apenas os tipos "TEndereco" e "TPessoa"
            List<string> validacao = ValidarDocumentoXML(dados, XSDFiles).ToList();

            if (validacao.Count > 0)
            {
                retorno = "Ocorreram os seguintes erros na validação:\n";
                foreach (var item in validacao)
                {
                    retorno += item;
                }
            }
            return retorno;
        }

        /// <summary>
        /// Este é um método genérico, que serve para validar qualquer o schema de qualquer tipo de arquivo xml
        /// </summary>
        private static ICollection<string> ValidarDocumentoXML(XmlDocument doc, ICollection<string> XSDFiles)
        {
            // Limpa a lista de falhas de schema
            falhas.Clear();
            try
            {
                // Adiciona todos os arquivos .xsd ao fluxo de validação
                foreach (var item in XSDFiles)
                {
                    doc.Schemas.Add(null, item);
                }
            }
            catch (System.Exception ex)
            {
                throw new Exception("Houve um erro ao incluir os arquivos XSD para validar o arquivo XML.\n" + ex.Message);
            }
            try
            {
                // Delegate responsável por manipular os erros ocorridos: ValidationCallBack()
                doc.Validate(ValidationCallBack);
            }
            catch (XmlSchemaValidationException ex)
            {
                throw new Exception("Houve um erro executar a validação do documento XML. " + ex.Message);
            }

            return falhas;
        }

        /// <summary> 
        /// Manipulador de erros do xml
        /// Sua finalidade é obter as mensagens de erro (disparadas pelo método "ValidarDocumentoXML") e as incluir a variável "falhas"
        /// </summary> 
        private static void ValidationCallBack(object sender, ValidationEventArgs args)
        {
            // Podem ser gerados dois tipos de falhas ("XmlSeverityType"), portanto, a estrutura abaixo, separa os erros entre "Alerta (Warning)" ou "Erros (Error)"
            if (args.Severity == XmlSeverityType.Warning)
            {
                falhas.Add("Alerta: " + TraduzMensagensDeErro(args.Message) + " (Caminho: " + ObtemCaminho(args) + ")");
            }
            else if (args.Severity == XmlSeverityType.Error)
            {
                falhas.Add("Erro: " + TraduzMensagensDeErro(args.Message) + " (Caminho: " + ObtemCaminho(args) + ")");
            }
        }

        /// <summary>
        /// Durante a validação do schema de um arquivo xml, este método auxilia na obtenção do caminho completo da tag que causou algum problema de validação
        /// </summary>
        private static string ObtemCaminho(ValidationEventArgs args)
        {
            // Captura a referência para a tag que causou o problema (falha de schema)
            XmlSchemaValidationException ex = (XmlSchemaValidationException)args.Exception;
            object sourceObject = ex.SourceObject;

            if (sourceObject.GetType() == typeof(XmlElement))
            {
                XmlElement tagProblema = (XmlElement)(sourceObject);
                return GetCaminhoTagXML(tagProblema.ParentNode) + "/" + tagProblema.Name;
            }
            else
            {
                return "";
            }
        }

        /// <summary>
        /// Devolve o caminho completo de um elemento de um documento XML, no padrão: "\elemento_raiz\elemento2\elemento3\..."
        /// </summary>
        private static string GetCaminhoTagXML(XmlNode args)
        {
            var node = args.ParentNode;
            if (args.ParentNode == null)
            {
                return "";
            }
            else if (args.ParentNode.NodeType == XmlNodeType.Element)
            {
                // Elemento atual é um nó com mais itens
                // Chama o próprio método recursivamente, para obter toda a árvore da tag atual
                return GetCaminhoTagXML(node) + @"/" + args.Name;
            }
            return "";
        }

        /// <summary>
        /// Altera o texto das mensagens de validação do schema, de inglês para português
        /// </summary>
        private static string TraduzMensagensDeErro(string mensagem)
        {
            mensagem = mensagem.Replace("The value of the 'Algorithm' attribute does not equal its fixed value.", "O valor do atributo 'Algorithm' não é igual ao seu valor fixo.");
            mensagem = mensagem.Replace("The '", "O elemento '");
            mensagem = mensagem.Replace("element is invalid", "é inválido");
            mensagem = mensagem.Replace("The value", "O valor");
            mensagem = mensagem.Replace("is invalid according to its datatype", "é inválido de acordo com o seu tipo de dados");
            mensagem = mensagem.Replace("The Pattern constraint failed.", "");
            mensagem = mensagem.Replace("The actual length is less than the MinLength value", "O comprimento real é menor que o valor MinLength");
            mensagem = mensagem.Replace(" in namespace 'http://www.w3.org/2000/09/xmldsig#'.", "");
            mensagem = mensagem.Replace("The element", "O elemento");
            mensagem = mensagem.Replace("has invalid child element", "tem um elemento filho inválido");
            mensagem = mensagem.Replace("List of possible elements expected:", "Lista de possíveis elementos esperados:");
            mensagem = mensagem.Replace("The Enumeration constraint failed.", "");
            mensagem = mensagem.Replace("http://www.w3.org/2000/09/xmldsig#:", "");
            mensagem = mensagem.Replace("http://www.w3.org/2001/XMLSchema:", "");
            mensagem = mensagem.Replace("The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.", "A entrada não é uma string Base-64 válida, pois contém um caractere não base 64, mais de dois caracteres de preenchimento ou um caractere ilegal entre os caracteres de preenchimento.");
            mensagem = mensagem.Replace("The required attribute", "O atributo obrigatório");
            mensagem = mensagem.Replace("is missing", "está ausente");
            mensagem = mensagem.Replace("has incomplete content", "tem conteúdo incompleto");
            mensagem = mensagem.Replace("as well as", "bem como");
            return mensagem;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Como a classe ficou um pouco extensa, utilizei comentários em pontos específicos para explicar cada detalhe que está sendo executado.

Após estas modificações, temos o serviço para validação de XML completamente funcional, para utilizarmos, basta injetá-lo no controller, faremos isto através de uma configuração no método ConfigureServices da classe Startup.

Mas primeiro, vamos incluir uma referência em nosso arquivo web.api.xml.schema.validation.csproj para o pacote Microsoft.AspNetCore.Mvc.NewtonsoftJson, que nos auxiliará a trabalhar com arquivos XML nos controllers da API.

Edite o conteúdo do arquivo web.api.xml.schema.validation.csproj incluindo a linha:

<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.3" />
Enter fullscreen mode Exit fullscreen mode

Deixando-o da seguinte forma:

<Project Sdk="Microsoft.NET.Sdk.Web">
    <PropertyGroup>
        <TargetFramework>net5.0</TargetFramework>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3"/>
        <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.3"/>
    </ItemGroup>
</Project>
Enter fullscreen mode Exit fullscreen mode

Após adicionar a referência para a biblioteca de serialização NewtonSoft edite o conteúdo do arquivo Startup.cs, deixando-o da seguinte forma:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using web.api.xml.schema.validation.Services.InterfacesServicos;
using web.api.xml.schema.validation.Services.Servicos;

namespace web.api.xml.schema.validation
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // Configurações da injeção de dependência do serviço validador de documentos XML
            services.AddScoped(typeof(IXMLValidationService), typeof(XMLValidationService));

            services.AddControllers();
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "web.api.xml.schema.validation", Version = "v1" });
            });

            //Inclusão do framework de serialização NewtonSoft
            services.AddControllers().AddNewtonsoftJson();

            //Ajuste para permitir receber conteudos do tipo XML nos controllers da API
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
                .AddNewtonsoftJson
                    (options => { }).AddXmlSerializerFormatters()
              .AddXmlDataContractSerializerFormatters();

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "web.api.xml.schema.validation v1"));
            }

            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

3. Criando o endpoint para receber os arquivos XML

A próxima e última etapa, será a criação do controller que receberá a string do XML e irá submetê-la à validação, por meio do serviço XMLValidationService.

Crie no diretório \Controllers o arquivo XMLValidationController.cs com o seguinte conteúdo:

using System.ComponentModel;
using Microsoft.AspNetCore.Mvc;
using web.api.xml.schema.validation.Services.InterfacesServicos;

[Description("Validação de XML")]
public class XMLValidationController : Controller
{
    //Interface do serviço que valida o arquivo XML e será injetado automaticamente em tempo de execução
    private readonly IXMLValidationService _XMLValidationService;

    public XMLValidationController(IXMLValidationService XMLValidationService)
    {
        _XMLValidationService = XMLValidationService;
    }

    [HttpPost("api/validarxml/")]
    public string Validar([FromBody] string strDocumento)
    {
        return _XMLValidationService.XMLValidate(strDocumento);
    }
}
Enter fullscreen mode Exit fullscreen mode


Todo o código da aplicação está pronto. Agora, ao executar nossa WEB API e navegar para o endereço: https://localhost:5001/swagger, teremos acesso ao novo endpoint XMLValidation conforme mostra a imagem a seguir:

Alt Text

Ao clicar no botão Try it out podemos testar o nosso mecanismo de validação, usando o seguinte payload:

"<?xml version='1.0' encoding='UTF-8'?>
<pessoa>
    <nome>Silvair</nome>
    <sobrenome>Leite Soares</sobrenome>
    <endereco>
        <logradouro>Rua Goia</logradouro>
        <complemento>Quadra e lote qualquer</complemento>
        <bairro>Setor Gentil Meirelles</bairro>
        <CEP>74575-200</CEP>
    </endereco>
</pessoa>"
Enter fullscreen mode Exit fullscreen mode

O schema será validado com sucesso, veja na imagem a seguir:

Alt Text

Alt Text

Mas se você fizer qualquer modificação no payload, de forma que o contrato (arquivos .xsd) seja quebrado, a API retornará todos os detalhes dos problemas ocorridos. Veja a seguir:

"<?xml version='1.0' encoding='UTF-8'?>
<pessoa>
    <nome>Silvair</nome>
    <sobrenome/>
    <endereco>
        <logradouro>Rua Goia</logradouro>
        <complemento>Quadra e lote qualquer</complemento>
        <bairro>Setor Gentil Meirelles</bairro>
        <ElementoNaoPrevisto>Texto qualquer</ElementoNaoPrevisto>
        <CEP>74575-200</CEP>
    </endereco>
</pessoa>"
Enter fullscreen mode Exit fullscreen mode


Omiti intencionalmente o conteúdo da tag sobrenome e inclui um elemento não previsto na tag endereco, veja o resultado:

Alt Text

Alt Text

Com este passo, concluímos o nosso projeto de teste. Lembrando que, por mais que estejamos validando os tipos "pessoa" e "endereco" durante este artigo, o serviço que construímos servirá para validar qualquer tipo de schema XML. Bastando para isso, incluir os respectivos arquivos .xsd no diretório \Schemas e fazer algumas pequenas modificações, como por exemplo, criar um endpoint específico para cada tipo de arquivo XML a ser validado.

Todo o código construído durante o projeto está disponível no seguinte repositório do GitHub: https://github.com/silvairsoares/web.api.xml.schema.validation

Referências:

MACORATTI, José Carlos. XML - Validando um Documento XML com um Schema (C#). Disponível em: http://www.macoratti.net/11/10/c_vxml1.htm. Acesso em: 13 de ago. de 2021.

Discussion (0)