Jak dodać instrukcję procesującą <?xml encoding> używając TXMLDocument?

0

Witam,
Podczas zapisu do pliku wcześniej załadowanego XML'a ze string'a komponent TXMLDocument usuwa mi atrubut encoding="utf-8".

var
    XMLTxt: string;
    xmldoc: TXMLDocument;
begin
  XMLTxt := '<?xml version="1.0" encoding="utf-8"?><First>1</First>';
  xmldoc.Active := True;
  xmldoc.Version := '1.0';
  xmldoc.Encoding := 'utf-8';
  xmldoc.LoadFromXML(XMLTxt);
  xmldoc.SaveToFile(XMLFile);
  xmldoc.Active := False;
end;

Plik XML zostaje utworzony na dysku, ale w jego zawartości brakuje encoding="utf-8". Pozostaje <?xml version="1.0"?><First>1</First>.
Dlaczego tak się dzieje?

1

ale to było trudne: https://www.google.com/search?q=delphi+TXMLDocument+encoding%3D%22utf-8%22 pierwszy link i już odpowiedź

0

Widziałem już ten link i próbowałem rozwiązań z niego. Niestety nic to mi nie dało.
Jak tylko wywołam oXml.LoadFromXML(XMLTxt); lub xmldoc.LoadFromXML(XMLTxt); to już nie mam encoding.
Nawet gdy wywołam XMLTxt := Xml.XMLDoc.FormatXMLData(XMLTxt) to też wycina encoding.

1
  1. odpowiadaj w postach, nie w komentarzu
  2. to czytałeś UTF-8 is XML's default encoding when no encoding attribute or BOM are present to indicate a different encoding is being used
  3. sam brak encoding="utf-8" gdzieś w czymś przeszkadza?
0
abrakadaber napisał(a):
  1. odpowiadaj w postach, nie w komentarzu
  2. to czytałeś UTF-8 is XML's default encoding when no encoding attribute or BOM are present to indicate a different encoding is being used
  3. sam brak encoding="utf-8" gdzieś w czymś przeszkadza?

Tak, czytałem informacje o UTF-8, że jest domyślnym kodowaniem.
Brak encoding przeszkadza ponieważ muszę policzyć hash z całej zawartości pliku i jeśli nie mam encoding to hash się nie zgadza.

2

Zmieniłem nieco kolejność instrukcji

procedure TForm1.Button6Click(Sender: TObject);
var
  XMLTxt: string;
begin
  XMLTxt := '<First>1</First>';
  xmldoc.Active := true;
  xmldoc.LoadFromXML(XMLTxt);
  xmldoc.Version := '1.0';
  xmldoc.Encoding := 'utf-8';
  xmldoc.SaveToFile(XMLFile);
  xmldoc.Active := False;
end;
0
grzegorz_so napisał(a):

Zmieniłem nieco kolejność instrukcji

procedure TForm1.Button6Click(Sender: TObject);
var
  XMLTxt: string;
begin
  XMLTxt := '<First>1</First>';
  xmldoc.Active := true;
  xmldoc.LoadFromXML(XMLTxt);
  xmldoc.Version := '1.0';
  xmldoc.Encoding := 'utf-8';
  xmldoc.SaveToFile(XMLFile);
  xmldoc.Active := False;
end;

Działa!. Dzięki bardzo. Nie pomyślałem, że kolejność może mieć tutaj znaczenie, ale jak tak się zastanowić to LoadFromXML ładuje zawartość z domyślnymi ustawieniami a dopiero po ustawieniu własnych wartości i wykonaniu SaveToFile zostaje plik zapisany z tym co się ustawiło.

0
jm0x01 napisał(a):

Brak encoding przeszkadza ponieważ muszę policzyć hash z całej zawartości pliku i jeśli nie mam encoding to hash się nie zgadza.

Jak dla mnie, to temat jest niejasny / być moze błednie postawiony
a) albo mówimy hash PLIKU, surowego pliku, array of byte , i NIE MOŻEMY angażować do tego parserów XML
b) albo mówimy o rozebranych z XML obiektach / kolekcjach (jak najbardziej jest tu miejsce na parser / komponent), ale to zupełnie inny hash

0
AnyKtokolwiek napisał(a):

Jak dla mnie, to temat jest niejasny / być moze błednie postawiony
a) albo mówimy hash PLIKU, surowego pliku, array of byte , i NIE MOŻEMY angażować do tego parserów XML
b) albo mówimy o rozebranych z XML obiektach / kolekcjach (jak najbardziej jest tu miejsce na parser / komponent), ale to zupełnie inny hash

Mówimy o hash PLIKU XML. Na początku próbowałem cały tekst zapisać do pliku XML używając TStringList albo nawet poprzez AssignFile,Rewrite itd. Niestety tutaj pojawia mi się błąd (załącznik).
Postanowiłem więc skorzystać z TXMLDocument aby zapisać tekst xml'a do pliku.Teraz już zapisuje prawidłowo i wszystko się zgadza.

1

Na początku próbowałem cały tekst zapisać do pliku XML używając TStringList albo nawet poprzez AssignFile,Rewrite itd. Niestety tutaj pojawia mi się błąd (załącznik).

Prawdopodobnie błąd wynika ze złego kodowania
Próbowałeś jak poniżej ?

  stringlist.SaveToFile(Filename,tencoding.UTF8)
0
grzegorz_so napisał(a):

Prawdopodobnie błąd wynika ze złego kodowania
Próbowałeś jak poniżej ?

  stringlist.SaveToFile(Filename,tencoding.UTF8)

Nie próbowałem, ale po Twojej sugestii sprawdziłem i już faktycznie błąd się nie pojawia. Jednak gdy zapiszę plik poprzez TStringList to rozmiar pliku mam o 3 bajty większy niż gdy zapisuję poprzez TXMLDokument. Przez tą różnicę nie zgadza się hash.

3

Jednak gdy zapiszę plik poprzez TStringList to rozmiar pliku mam o 3 bajty większy niż gdy zapisuję poprzez TXMLDokument

Prawdopodobnie różnica wynika z tego, że TStringList zapisuje plik z BOM:

https://stackoverflow.com/questions/32274712/how-can-i-save-a-object-from-tstringlist-class-to-file-delphi-xe-2-with-utf8-w

0
Panczo napisał(a):

Prawdopodobnie różnica wynika z tego, że TStringList zapisuje plik z BOM:

https://stackoverflow.com/questions/32274712/how-can-i-save-a-object-from-tstringlist-class-to-file-delphi-xe-2-with-utf8-w

Dokładnie o to chodziło. Gdy ustawiłem TStringList.WriteBOM := False to wszystko się zgadza. A tak przy okazji, to lepiej używać TStringList czy TXMLDocument? Chodzi konkretnie tylko o zapisanie do pliku.

1 użytkowników online, w tym zalogowanych: 0, gości: 1