Estava recompilando alguns componentes do meu sistema, desenvolvidos originalmente com o Delphi 7 para o Delphi 2010, e percebi o seguinte erro ao tentar abrir um XML gerado pela aplicação compilada com o D2010 “caractere inválido encontrado no texto“.

Na verdade o XML contêm campos acentuados usando “ISO-8859-1″ e, após algum tempo perdido descobri que o código abaixo, embora estivesse correto não gerava o XML como deveria; ou seja, a propriedade “encoding” simplesmente não é adicionada (como deveria) no cabeçalho do XML. Isso não acontece no Delphi 7, por exemplo.

01 – Codigo que não funciona no Delphi 2010:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  // Gerar o XML
  vXMLDoc := TXMLDocument.Create(self);
  try
  With vXMLDoc do begin
       Active := True;
       Encoding := 'ISO-8859-1';
       Version := '1.0';
 
       AddChild('0150');
       Node150 := DocumentElement;
       With IBQLv150 do begin
          while not eof do begin
             NodeDados := Node150.AddChild('participante');
             With NodeDados do
             begin
               AddChild('COD_PART').Nodevalue := FieldByname('registro').AsString+
               FieldByName('tipo').AsString;
               AddChild('NOME').Nodevalue := FieldByname('participante').AsString;
               AddChild('COD_PAIS').Nodevalue := '01058';
               //...cont.
             end;
             next;
          end;
       end;
  end; // vxmldoc
  Result := vXMLdoc.XML.Text
  finally
      vXMLDoc.Free;
  end;

Após descobrir o problema, fui atrás de uma possível solução no “QualityCentral” da Embarcadero e, descobri ali uma solução “paliativa” para o problema. Primeiro, o encoding somente é adicionado ao XML se for informado o valor “UTF-16″. Mas, essa codificação não é a que eu preciso e dai?

A solução (clique aqui para ver no QualityCentral) se dá através de um pequeno “macete”; gere o XML com “UTF-16″ e, em seguida execute um replace antes de devolver o conteúdo; como pode ser visto na linha X do código após aplicado o “macete”.

02 – Codigo modificado (repare linhas 6 e 26), contendo solução para usar o encoding no Delphi 2010:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  // Gerar o XML
  vXMLDoc := TXMLDocument.Create(self);
  try
  With vXMLDoc do begin
       Active := True;
       Encoding := 'UTF-16';
       Version := '1.0';
 
       AddChild('0150');
       Node150 := DocumentElement;
       With IBQLv150 do begin
          while not eof do begin
             NodeDados := Node150.AddChild('participante');
             With NodeDados do
             begin
               AddChild('COD_PART').Nodevalue := FieldByname('registro').AsString+
               FieldByName('tipo').AsString;
               AddChild('NOME').Nodevalue := FieldByname('participante').AsString;
               AddChild('COD_PAIS').Nodevalue := '01058';
               //...cont.
             end;
             next;
          end;
       end;
  end; // vxmldoc
  Result := STRTRAN(vXMLdoc.XML.Text,'UTF-16','UTF-8'); 
  finally
      vXMLDoc.Free;
  end;

Funciona, mas, vamos aguardar uma solução definitva não é mesmo?.

Posts Relacionados

Tags: , , ,



2 Comentários to “Delphi 2010, Problema com “encoding” usando TXMLDocument”

  1. David Alves | janeiro 10th, 2010 at 14:41

    Caro Caio,
    Este post traz informações muito importantes.
    Gostaria de saber se além de mudar a propriedade “encoding”, consigo mudar o formato das tags, ao invés de sair , sair igual ao exemplo abaixo.

    Qual o comando para criar a tag Package e depois criar as outras tags dentro dela, observando que a tag package fecha com e as outras apenas com />.

  2. admin | janeiro 11th, 2010 at 10:38

    Conforme recebi no seu e-mail; o XML que vc. quer montar abaixo:

    <?xml version="1.0" encoding="ASCII"?>
    <Package>
    <Header Version="2.1" Id="1" />
    <Data Usuario="eagle" Senha="eagle" />
    </Package>

    Vc. pode usar o código exemplo abaixo:

      vXMLDoc := TXMLDocument.Create(self);
      Try
      With vXMLDoc do begin
           Active := True;
           Version := '1.0';
           Encoding := 'ASCII';
           // Adiciona Pckage
           AddChild('Package');
           NodeA := Node.ChildNodes['Package'];
           // Adiciona Header em Package
           NodeA.AddChild('Header');
           NodeA.ChildNodes['Header'].Attributes['Version'] := '2.1';
           NodeA.ChildNodes['Header'].Attributes['Id'] := '1';
           // Adiciona Data em Package
           NodeA.AddChild('Data');
           NodeA.ChildNodes['Data'].Attributes['Usuario'] := 'eagle';
           NodeA.ChildNodes['Data'].Attributes['Senha'] := 'eagle';
      end;
      vXMLDoc.SaveToFile('exemplo.xml');
      finally
         vXMLDoc.Free;
      end;

    No caso do D2010; adicione o macete explicado nesse tópico para substituir o encoding.

Faça um comentário