I am using Delphi7 ClientDataSet to read and write xml files for some of my data.
Howerver, when I want to browse this outside the program (double clicking the xml in Windows Explorer) I get the 'An invalid character was found in text content. Error processing resource' - even although the data reads and writes fine from within Delphi.
Is there a way to force TClientDataSet to write it's contents in an indented way in stead in one line ?
That way I could easily open it into a text editor and find what character will trigger the above error.
Anyway: I find it much more clearer for an XML file to be written with CR/LF and indents anyway.
Thx in advance.
It's because the proper encoding (like <?xml version="1.0" encoding="UTF-8"?>
) has not be specified in your output file, yet it contains some characters with an incompatible encoding.
As RRUZ mentioned, specifying explicitly the TDataPacketFormat
as dfXMLUTF8
when writing the file will most certainly solve the 'Invalid Character' error, as it will write the encoding tag first:<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <DATAPACKET Version="2.0">[...]
You can also add the encoding manually at the beginning of the file for already existing files.
As for the readable formatting, some readers can read the raw one-liner and do the formatting for you (browsers like FireFox or Internet Exporer, and XML editors like XMLNotePad)
When you uses the TCustomClientDataSet.SaveToFile
procedure, you can choose the output format, for default this value is set to dfBinary
wich encode the data in a binary format.
procedure TCustomClientDataSet.SaveToFile(const FileName: string = '';
Format: TDataPacketFormat = dfBinary);
try changing the Format
parameter to dfXML
or dfXMLUTF8
ClientDataSet1.SaveToFile('file.xml',dfXML);
if you want format the XML output you can use the FormatXMLData
function try this code
uses
XMLDoc;
Procedure FormatXMLFile(XmlFile:string);
var
oXml : TXMLDocument;
begin
oXml := TXMLDocument.Create(nil);
try
oXml.LoadFromFile(XmlFile);
oXml.XML.Text:=xmlDoc.FormatXMLData(oXml.XML.Text);
oXml.Active := true;
oXml.SaveToFile(XmlFile);
finally
oXml := nil;
end;
end;
finally you code will look like this
ClientDataSet1.SaveToFile('test.xml',dfXML);
FormatXMLFile('test.xml');
I modified your code, because I had some problems with UTF-8:
Procedure FormatXMLFile(XmlFile:string);
var
oXml : TXMLDocument;
s : utf8String;
begin
oXml := TXMLDocument.Create(nil);
try
oXml.LoadFromFile(XmlFile);
s := oxml.XML.Text;
s := StringReplace(s, '><', '>' + #13#10 + '<' , [rfReplaceAll]);
//oXml.XML.Text:=xmlDoc.FormatXMLData(oxml.XML.Text);
oxml.XML.Text := s;
oXml.Active := true;
oXml.SaveToFile(XmlFile);
finally
oXml := nil;
end;
end;
来源:https://stackoverflow.com/questions/3848853/using-delphi7-tclientdataset-is-it-possible-to-have-it-save-its-xml-contents-i