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: , , ,



12 Comentários

  • At 2010.01.10 14:41, David Alves said:

    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 />.

    • At 2010.01.11 10:38, admin said:

      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.

      • At 2010.08.26 20:13, Eduardo said:

        Pessoal,

        Reportei este erro ano passado no Quality Central (QC 80008) e os caras não consegue entender um erro básico no XML, peços-lhe a todos que votem no meu QC e comentem sobre o problema para ver se conseguem corrigir rápido isto, 1 ano e nada de correção do Delphi sobre este problema, sei que existe “macetes” para contornar, mas é brincadeira, a ferramenta não pode cometer tal erro e ficar deste jeito… valeu galera…

        • At 2010.08.27 12:02, admin said:

          Olá Eduardo,

          Realmente, ainda no Delphi 2010, o problema existe. A solução temporária é simples, basta inserir uma linha no código para resolver o problema. Segue abaixo:

          Crie o XML com UTF-16 e, quando o seu XML estiver pronto para resposta, execute o codigo abaixo:

          Result := STRTRAN(vXMLDoc.XML.Text, 'UTF-16', 'ISO-8859-1');

          Sds

          • At 2010.09.22 19:14, Eduardo said:

            Olá Caio,

            Estou implementando a NFe 2.0 e me deparei com um problema, como pegar uma Tag de um nós em um XML da 2.0, por exemplo a Tag “nRec”, tem alguma idéia utilizando comando XML, segue abaixo:

            35
            2.00

            2
            SP_NFE_PL_006e
            103
            Lote recebido com sucesso
            35
            2010-09-22T11:48:51

            351000021551142
            1

            • At 2010.09.22 19:19, Eduardo said:

              ****

              35
              2.00

              2
              SP_NFE_PL_006e
              103
              Lote recebido com sucesso
              35
              2010-09-22T11:48:51

              351000021551142
              1

              *****

              • At 2010.09.22 19:20, Eduardo said:

                não estou conseguindo colocar aqui o XML para exemplo

                • At 2010.09.22 19:23, Eduardo said:

                  35
                  2.00

                  2
                  SP_NFE_PL_006e
                  103
                  Lote recebido com sucesso
                  35
                  2010-09-22T11:48:51

                  351000021551142
                  1

                  • At 2010.10.26 12:50, Otavino said:

                    Valeu Caio foi de fundamental importância sua dica, foi o primeiro post que achei.

                    Um fraterno abraço.

                    • At 2011.01.29 21:51, Jayme said:

                      Caio, preciso criar o XML em memória. Há valores acentuados. Os caracteres são trocados por representação UTF-8. Estou atualmente fazendo uma “gambiarra”. Salvo o XML em TStrings, troco o cabeçalho e substituo os caracteres como “ç” usando StringReplace.

                      Gostaria de uma versão com menos problemas. Estou usando no C++Builder 6.0 Professional.

                      • At 2011.04.20 12:35, daniel said:

                        estou com esse problema de enconding tambem…. uso o delphi 2009
                        gero xml atraves :
                        XMLDocument1.SaveToFile(‘c:\teste\teste.xml’);
                        quando abro o arquivo pelo IE aparece aquele “erro”:

                        nao consegui entender como implementar essa rotina acima descrita junto com o procedimento savetofile….
                        desde ja muito obrigado por qualquer atencao
                        Daniel

                        • At 2011.04.20 18:26, Anônimo said:

                          Vc deve, antes de salvar o arquivo usar a função abaixo StringReplace (StrTran no meu caso) para substituir o encodind dentro do texto do XML.

                          Sds

                          You must be logged in to post a comment.