Jump to content


Photo

Xml Export and Import


  • Please log in to reply
2 replies to this topic

#1 wvd_vegt

wvd_vegt

    Master Member

  • Honorable Members
  • PipPipPipPipPip
  • 710 posts
  • Gender:Male
  • Location:the Netherlands

Posted 18 March 2005 - 10:47 PM

Hi,

Certainly not production code but it worked fine on a test grid. Note the export is slightly changed (it exports attributes on the Column tag) since the previous post:

CODE
procedure TForm1.ExportToXml(const GridView: TGridView; const fn: string);

var

 r, c              : Integer;

 sl                : TStringList;



 function EscapeValue(const value: string): string;

 begin

 //Not implemented yet.

 //Change all characters outside the letters, numbers and crlf to

 //< format where 3C is the hex value of the Characters Ord.

    Result := value;

 end;



begin

 sl := TStringList.Create;



 sl.Add('<?xml version="1.0"?>');

 sl.Add(Format('<GridView version = "%s">', ['2.4.1']));                       //Should be stVersion!



 sl.Add(' <Columns>');

 for c := 0 to Pred(GridView.Columns.Count) do

   begin

   //Use Attributes to Export Column Dependend settings like min/max values.

     sl.Add(Format('  <Column Name="%s" ColumnClass="%s">', [GridView.Columns[c].Name, GridView.Columns[c].ClassName]));

     sl.Add('    ' + EscapeValue(GridView.Columns[c].Header.Caption));

     sl.Add('  </Column>');

   end;

 sl.Add(' </Columns>');



 sl.Add(' <Rows>');

 for r := 0 to Pred(GridView.RowCount) do

   begin

     sl.Add('  <Row>');

     for c := 0 to Pred(GridView.Columns.Count) do

       begin

         sl.Add('   <Cell>');

        {if not (GridView.Columns[c].ClassNameIs('TGraphicColumn') or

           GridView.Columns[c].ClassNameIs('TImageColumn')) then}

         sl.Add('    ' + EscapeValue(GridView.Cell[c, r].AsString));

         sl.Add('   </Cell>');

       end;

     sl.Add('   </Row>');

   end;

 sl.Add(' </Rows>');



 sl.Add('</GridView>');



 sl.SaveToFile(fn);

 sl.Free;

end;


And the import:

CODE
procedure TForm1.ImportFromXml(const GridView: TGridView; const fn: string);



var

 sl                : TStringList;



 function FetchAttributes(tag, value: string; var a: TStringList): string;

 var

   i               : Integer;

   s               : string;

 begin

   //Fetch the attributes into a TStringList.

   Result := value;

   Delete(Result, 1, Length(Format('<%s ', [tag])));

   Delete(Result, Pos('>', Result), Length(Result));

   a.Text := Trim(Result);



   //Return the input value without the Attributes.

   Result := value;

   Delete(Result, 1, Pos('>', Result) + 1);

   Result := Format('<%s>', [tag]) + Result;



   //Remove Surrounding Quotes from Value.

   for i := 0 to Pred(a.Count) do

     begin

       s := a.Values[a.Names[i]];

       if (s[1] = '"') and (s[Length(s)] = '"') then

         begin

           Delete(s, 1, 1);

           Delete(s, Length(s), 1);

         end;

       a.Values[a.Names[i]] := s;

     end;

 end;



 function FetchInnerText(tag, value: string): string;

 begin

   //Fetch the Text between a start and end tag.

   Result := value;

   Delete(Result, 1, Length(Format('<%s>', [tag])));

   while not (AnsiEndsText(Format('</%s>', [tag]), Result)) do

     begin

       Result := Result + Trim(sl[0]);

       sl.Delete(0);

     end;

   Delete(Result, Pos(Format('</%s>', [tag]), Result), Length(Result));

   Result := Trim(Result);

 end;



type

 states = (xmlNone, xmlHeader, xmlGridView, xmlColumns, xmlColumn, xmlRows, xmlRow, xmlCells, xmlCell);



var

 r, c              : Integer;

 i                 : Integer;

 s, value          : string;

 state             : states;

 a                 : TStringList;



begin

 sl := TStringList.Create;



 GridView.ClearRows;

 for i := 0 to Pred(GridView1.Columns.Count) do

   GridView1.Columns[i].Header.Caption := '';

 GridView1.Update;



 sl.LoadFromFile(fn);



 r := 0;

 c := 0;



 state := xmlNone;



 repeat

   s := Trim(sl[0]);

   sl.Delete(0);



   if (CompareText(s, '<?xml version="1.0"?>') = 0) then                       //Process XML Version

     begin

       if (state <> xmlNone) then

         begin

           ShowMessage('Xml header not found.');

           Break;

         end

       else

         state := xmlHeader;

     end



   else if (CompareText(s, '<GridView version = "2.4.1">') = 0) then           //Process GridView Tag

     state := xmlGridView



   else if (CompareText(s, '<Columns>') = 0) then                              //Process Columns Tag

     begin

     //sl.Add(Format('  <Column Name="%s" ColumnClass="%s">', [GridView.Columns[c].Name, GridView.Columns[c].ClassName]));

     //sl.Add('    ' + EscapeValue(GridView.Columns[c].Header.Caption));

       c := 0;

       State := xmlColumns;

     end

   else if AnsiStartsText('<Column ', s) then                                  //Process Column Tag

     begin

       State := xmlColumn;

       a := TStringList.Create();

       s := FetchAttributes('Column', s, a);

       s := FetchInnerText('Column', s);

       GridView.Columns[c].Header.Caption := s;



       //Use StringList 'a' here to restore Column Class Dependend Values (like min/max).

       //This information can also be cached to match <Cell> tags to the correct column

       //so importing data after changing the order of the columns is also supported.



       Inc(c);

       a.Free;

       State := xmlColumns;

     end

   else if (CompareText(s, '</Columns>') = 0) then                             //Finished Processing Columns Tag

     begin

       c := 0;

       State := xmlGridView;

     end



   else if (CompareText(s, '<Rows>') = 0) then                                 //Process Rows Tag

     begin

       State := xmlRows;

     end

   else if (AnsiStartsText(s, '<Row>')) then                                   //Process Row Tag

     begin

       Inc(r);

       GridView.AddRow();

       c := 0;

       State := xmlRows;

     end

   else if AnsiStartsText('<Cell>', s) then                                    //Process Cell Tag

     begin

       State := xmlCell;

       GridView.Cell[c, Pred(GridView.RowCount)].AsString := FetchInnerText('Cell', s);

       Inc(c);

       State := xmlCells;

     end

   else if (CompareText(s, '</Row>') = 0) then                                 //Finished Processing Row Tag

     begin

       State := xmlRows;

     end

   else if (CompareText(s, '</Rows>') = 0) then                                //Finished Processing Rows Tag

     begin

       State := xmlGridView;

     end

   else if (CompareText(s, '</GridView>') = 0) then                            //Finished Processing GridView Tag

     state := xmlNone;



 until sl.Count = 0;



 sl.Free;

end;


Tested on TTextualColumn, TNumericColumn, TCheckBoxColumn and TPorgressColumn. Guess all non image/html ones will work if there are no strange symbols in the text as there isn't any escaping implemented yet.
G.W. van der Vegt

#2 HL Arledge

HL Arledge
  • Members
  • 11 posts

Posted 02 October 2006 - 02:33 AM

Thank you, wvd_vegt.

This is very valuable code. The contribution is greatly appreciated!

#3 wvd_vegt

wvd_vegt

    Master Member

  • Honorable Members
  • PipPipPipPipPip
  • 710 posts
  • Gender:Male
  • Location:the Netherlands

Posted 02 October 2006 - 06:05 PM

Hi,

QUOTE (HL Arledge @ Oct 2 2006, 03:33 AM) <{POST_SNAPBACK}>
This is very valuable code. The contribution is greatly appreciated!


Thanks, as usual enjoy the code.
G.W. van der Vegt




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users