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.

Dica!
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, ou um objeto instanciado.

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.

Top comments (0)