Validação de XML em Delphi

Validação de XML em Delphi
XML

Introdução

Neste post iremos abordar sobre Validação de XML em Delphi.

A validação de arquivos XML é uma etapa crucial no desenvolvimento de sistemas que utilizam essa estrutura de dados para troca de informações. Garantir que o conteúdo XML esteja em conformidade com um esquema XSD (XML Schema Definition) ajuda a evitar erros de processamento, garantir a integridade dos dados e assegurar que o XML segue as regras esperadas. Neste artigo, abordaremos como realizar a validação de XML contra um esquema XSD no Delphi, bem como técnicas para tratar erros de validação e depuração.

O que é um Esquema XSD?

O XML Schema Definition (XSD) é uma linguagem que define a estrutura e as regras de validação de um documento XML. Ele especifica os tipos de dados, a obrigatoriedade de elementos e a ordem em que eles devem aparecer. Validar um XML contra um XSD assegura que o documento segue o formato esperado, evitando problemas futuros no uso desses dados.

Exemplo de um Arquivo XSD e seu XML

Claro! A seguir está um exemplo de um arquivo XSD que define a estrutura de um documento XML contendo informações de uma pessoa (nome, idade e endereço):

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <!-- Elemento raiz -->
  <xs:element name="Pessoa">
    <xs:complexType>
      <xs:sequence>
        <!-- Definindo os elementos dentro de "Pessoa" -->
        <xs:element name="Nome" type="xs:string" />
        <xs:element name="Idade" type="xs:int" />
        <xs:element name="Endereco">
          <xs:complexType>
            <xs:sequence>
              <!-- Definindo os elementos dentro de "Endereco" -->
              <xs:element name="Rua" type="xs:string" />
              <xs:element name="Cidade" type="xs:string" />
              <xs:element name="CEP" type="xs:string" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

</xs:schema>

Estrutura do XSD:

  1. Elemento raiz “Pessoa”: Este elemento contém os detalhes da pessoa.
  2. Elemento “Nome”: Um elemento do tipo string que armazena o nome da pessoa.
  3. Elemento “Idade”: Um elemento do tipo int que armazena a idade da pessoa.
  4. Elemento “Endereco”: Um elemento complexo que contém os detalhes do endereço, incluindo a rua, cidade e CEP, todos definidos como string.

Esse XSD descreve as regras que o XML deve seguir. Por exemplo, o documento XML que seria válido com base nesse XSD poderia ser:

<?xml version="1.0" encoding="UTF-8"?>
<Pessoa>
  <Nome>João Silva</Nome>
  <Idade>30</Idade>
  <Endereco>
    <Rua>Rua das Flores, 123</Rua>
    <Cidade>São Paulo</Cidade>
    <CEP>01234-567</CEP>
  </Endereco>
</Pessoa>

Se o XML não seguir a estrutura ou os tipos de dados especificados no XSD (como uma idade que não seja um número), ele não será validado corretamente.

Como Validar XML Contra um Esquema XSD

Delphi oferece a classe TXMLDocument, que facilita o carregamento e a manipulação de arquivos XML. No entanto, a validação contra um XSD não é diretamente suportada pela VCL nativa. Para realizar essa validação, utilizamos bibliotecas externas como MSXML (Microsoft XML Core Services), que possuem suporte completo para validação de XML.

Abaixo, vamos utilizar o MSXML, uma biblioteca amplamente usada no Windows, para validar XML no Delphi.

Criamos os objetos em cache para facilitar o uso, e utilizaremos a biblioteca ComObj, nativa do Delphi.

Carregando e Validando um XML

O código a seguir demonstra como carregar um XML e validar contra um esquema XSD utilizando MSXML no Delphi:

uses
  ComObj, SysUtils, Dialogs;

function TForm1.ValidarXmlComXsd(FileXml, FileXsd: string): TStringList;
var
  XML, XSDL: Variant;

  procedure LerXml(XmlNode: Variant; var Xml: Variant; var Result: TStringList);
  var
    i: integer;
    AttrNode: Variant;
    Erro: String;

  begin

    for i := 0 to XmlNode.childNodes.length -1 do
    begin
      AttrNode := XmlNode.childNodes.item[i];

      if Trim(AnsiLowerCase(AttrNode.nodeTypeString)) = 'element' then
      begin

        Erro := Trim(Xml.validateNode(AttrNode).reason);

        If (Erro <> '') then
        begin
          if Result.Count = 0 then
            Result.Add(Erro)
          else
          if Result[Result.Count-1] <> Erro then
            Result.Add(Erro);
        end;

        LerXml(AttrNode, Xml, Result);

      end;
    end;
  end;

begin
  try
    Result := TStringList.Create;
    Result.Clear;
    XSDL := CreateOLEObject('MSXML2.XMLSchemaCache.6.0');  //Cria o objeto XSDL
    XSDL.validateOnLoad := True;
    XSDL.add('',FileXsd);
    XML := CreateOLEObject('MSXML2.DOMDocument.6.0'); //Cria o objeto XML
    XML.validateOnParse := False;
    XML.resolveExternals := True;
    XML.schemas := XSDL;
    XML.load(FileXml); //Carrega o XML
    LerXml(xml, xml, Result); //Lê e retorna o erro caso exista
  finally
    XSDL := varNull;
    XML := varNull;
  end;
end;

Explicação do Código

O código apresentado utiliza a biblioteca MSXML para validar um arquivo XML contra um arquivo de esquema XSD, e a função principal é ValidarXmlComXsd. Vamos detalhar o que cada parte do código faz:

  1. Objetivo da Função:
    A função ValidarXmlComXsd recebe dois parâmetros:
  • FileXml: o caminho do arquivo XML que será validado.
  • FileXsd: o caminho do arquivo XSD (esquema) que será usado para validar o XML. Ela retorna uma lista (TStringList) contendo possíveis erros de validação, caso existam.
  1. Bibliotecas Utilizadas:
    O código utiliza MSXML (Microsoft XML Core Services), especificamente as classes:
  • MSXML2.XMLSchemaCache.6.0: para lidar com o arquivo XSD.
  • MSXML2.DOMDocument.6.0: para carregar e manipular o arquivo XML.

Explicação Linha por Linha

Inicialização e Criação de Objetos
XSDL := CreateOLEObject('MSXML2.XMLSchemaCache.6.0');  //Cria o objeto XSDL
XSDL.validateOnLoad := True;
XSDL.add('', FileXsd);
  • Aqui, o código cria um objeto XMLSchemaCache.6.0, responsável por gerenciar os esquemas XSD.
  • A linha XSDL.validateOnLoad := True; define que o arquivo XSD será validado automaticamente ao ser carregado.
  • A função XSDL.add adiciona o esquema XSD ao cache de esquemas, para que possa ser usado durante a validação.
Carregamento e Configuração do XML
XML := CreateOLEObject('MSXML2.DOMDocument.6.0'); //Cria o objeto XML
XML.validateOnParse := False;
XML.resolveExternals := True;
XML.schemas := XSDL;
XML.load(FileXml); //Carrega o XML
  • O objeto DOMDocument.6.0 é criado para carregar o arquivo XML.
  • A linha XML.validateOnParse := False; desativa a validação automática durante a análise (parsing) do XML.
  • XML.resolveExternals := True; permite que o XML resolva referências externas, caso elas existam.
  • A propriedade XML.schemas := XSDL; associa o cache de esquemas (com o arquivo XSD) ao documento XML.
  • Finalmente, XML.load(FileXml); carrega o arquivo XML.
Função Recursiva para Validação
procedure LerXml(XmlNode: Variant; var Xml: Variant; var Result: TStringList);
  • Esta função é chamada para percorrer os nós do XML e validar cada um deles usando a função validateNode.
Validação de Cada Nó
Erro := Trim(Xml.validateNode(AttrNode).reason);
If (Erro <> '') then
begin
  if Result.Count = 0 then
    Result.Add(Erro)
  else
    if Result[Result.Count-1] <> Erro then
      Result.Add(Erro);
end;
  • validateNode(AttrNode) valida o nó atual. Se houver algum erro, ele é capturado na variável Erro.
  • Se um erro for encontrado, ele é adicionado à lista Result. Caso o erro já esteja na lista, ele não é duplicado.
Limpeza e Retorno
finally
  XSDL := varNull;
  XML := varNull;
end;
  • Após o processamento, os objetos XSDL e XML são liberados, evitando vazamento de memória.
  • A função retorna a lista Result contendo os erros encontrados.

Depuração de Problemas Comuns

Durante a validação de XML, alguns erros comuns podem ocorrer:

  1. Elemento Esperado, mas Ausente: Isso ocorre quando o XML não contém um elemento obrigatório definido no XSD. Exemplo de erro:
   O elemento 'Endereco' é esperado, mas não foi encontrado.

Solução: Verifique se todos os elementos obrigatórios estão presentes no XML e se eles estão posicionados corretamente.

  1. Tipo de Dados Inválido: Um valor de elemento ou atributo não está no formato especificado no XSD. Exemplo de erro:
   O valor 'abc' não é válido para o elemento 'Idade' de tipo 'int'.

Solução: Garanta que os valores no XML atendam às especificações de tipo de dado do XSD.

  1. Namespace Incompatível: O namespace do XML não corresponde ao esperado pelo XSD. Solução: Verifique se o namespace declarado no XML corresponde ao que está definido no XSD.

Veja abaixo a ilustração do projeto:

Ilustração do projeto.

Código fonte do exemplo

Você pode fazer o download do exemplo do projeto através do repositório do github:

https://github.com/Gisele-de-Melo/ValidarXML

Conclusão

A validação de XML contra um esquema XSD é uma prática que garante a integridade e confiabilidade dos dados em aplicações que utilizam esse formato. Utilizando o Delphi com a biblioteca MSXML, é possível validar documentos XML de maneira eficiente, capturando e tratando erros detalhados para garantir que o XML siga as regras definidas no XSD.

Essa abordagem não só melhora a qualidade do software, como também facilita a manutenção e depuração do sistema. Implementar a validação desde o início no desenvolvimento de aplicações pode evitar diversos problemas no futuro, principalmente em sistemas que dependem de trocas de dados complexas e em grande volume.

Por isso, ao trabalhar com XML, sempre considere a validação como uma etapa essencial para garantir o sucesso do seu projeto.

Posts Relacionados


Livros + e-books

Delphi para Android e iOS

codedelphi.com
codedelphi.com

Delphi Start

codedelphi.com

Programando em Delphi XE

Aprenda programar Delphi

Banco de Dados RAD Delphi

Delphi Programming Projects

Deixe um comentário