-2

How to open/load data from an xml file into tcxgrid in delphi?

Kromster
  • 7,181
  • 7
  • 63
  • 111
Sharpie
  • 373
  • 2
  • 15
  • 34
  • Delphi comes with an XML Mapper tool which you can use to transform XML into the format which a TClientDataSet can use. Then, you use a TXmlTransformProvider as the input to your CDS, and the CDS supplies the data to the cxGrid via a DataSource. This is all explained in detail in the OLH. – MartynA Sep 25 '14 at 15:46
  • 1
    StackOverflow is a difficult community. Why people are so quickly downvoting (especially a beginner) instead of helping improving the question? – Gabriel Sep 25 '14 at 20:50
  • @Dag-Improve your question else they will close it. Show the code that you have and show the problems. – Gabriel Sep 25 '14 at 20:52
  • @Dag is it XML data wich originates from an other cxGrid or is it from another source. Any by the way wich Delphi version – Jens Borrisholt Sep 26 '14 at 03:58
  • @dag before I herar from you again I wont make an Example to you, since it might be waste of time. My Time – Jens Borrisholt Sep 26 '14 at 13:51
  • Apologies for late reply, It is straight from an xml file, not another grid. The version of Delphi is XE2. Unfortunately I don't have anything to show at the moment. All I can say is I have a form with the cxgrid on it, also a button and when clicked this launches the topendialog function, I would then like to browse to the xml file and when click on, this will read in the xml file into the cxgrid. – Sharpie Oct 01 '14 at 14:31

1 Answers1

1

First of all, you didn't provide any XML data, so I've used this:

<?xml version="1.0"?>
<Tests>
  <Test TestId="0001" TestType="CMD">
    <Name>Convert number to string</Name>
    <CommandLine>Examp1.EXE</CommandLine>
    <Input>1</Input>
    <Output>One</Output>
  </Test>
  <Test TestId="0002" TestType="CMD">
    <Name>Find succeeding characters</Name>
    <CommandLine>Examp2.EXE</CommandLine>
    <Input>abc</Input>
    <Output>def</Output>
  </Test>
  <Test TestId="0003" TestType="GUI">
    <Name>Convert multiple numbers to strings</Name>
    <CommandLine>Examp2.EXE /Verbose</CommandLine>
    <Input>123</Input>
    <Output>One Two Three</Output>
  </Test>
  <Test TestId="0004" TestType="GUI">
    <Name>Find correlated key</Name>
    <CommandLine>Examp3.EXE</CommandLine>
    <Input>a1</Input>
    <Output>b1</Output>
  </Test>
  <Test TestId="0005" TestType="GUI">
    <Name>Count characters</Name>
    <CommandLine>FinalExamp.EXE</CommandLine>
    <Input>This is a test</Input>
    <Output>14</Output>
  </Test>
  <Test TestId="0006" TestType="GUI">
    <Name>Another Test</Name>
    <CommandLine>Examp2.EXE</CommandLine>
    <Input>Test Input</Input>
    <Output>10</Output>
  </Test>
</Tests>

Tha data are saved along with the exefile under the name test.xml

I use a property to get the name:

property XMLFileName: String read GetXMLFileName;

and the implementation:

function TForm8.GetXMLFileName: String;
begin
  Result := ExtractFilePath(Application.ExeName) + 'test.xml';
end;

then something to convert the XML file to a Dataset:

procedure TForm8.DomToDataset(XMLNode: IXMLNode; Dataset: TDataset);
var
  AttrNode: IXMLNode;

  procedure CreateFields;
  var
    StringField: TStringField;
    i: Integer;
    ChildNode: IXMLNode;
  begin
    for i := 0 to AttrNode.ChildNodes.Count - 1 do
    begin
      ChildNode := AttrNode.ChildNodes.Get(i);
      StringField := TStringField.Create(Dataset);
      StringField.Size := 50;
      StringField.FieldName := ChildNode.NodeName;
      StringField.DisplayLabel := ChildNode.NodeName;
      StringField.Dataset := Dataset;
      StringField.Name := 'StringField' + IntToStr(Dataset.Fields.Count + 1);
    end;
  end;

var
  i, J: Integer;
begin
  Dataset.Close;
  Dataset.Fields.Clear;

  for i := 0 to XMLNode.ChildNodes.Count - 1 do
  begin
    AttrNode := XMLNode.ChildNodes.Get(i);

    if Dataset.Fields.Count = 0 then
      CreateFields;

    Dataset.Open;

    Dataset.Append;
    try
      for J := 0 to AttrNode.ChildNodes.Count - 1 do
        Dataset.Fields[J].Value := AttrNode.ChildNodes.Get(J).NodeValue;

      Dataset.Post;
    except
      Dataset.Cancel;
    end;
  end;
end;

It is far from perfect, but it gives you the picture. Finally, we need to bind it all together:

procedure TForm8.FillGrid;
var
  XMLDocument: TXMLDocument;
  i: Integer;
begin
  XMLDocument := TXMLDocument.Create(nil);
  XMLDocument.LoadFromFile(XMLFileName);
  XMLDocument.Active := True;

  DomToDataset(XMLDocument.DocumentElement, dxMemData1);
  FreeAndNil(XMLDocument);
  dxMemData1.Active := True;

  cxGrid1DBTableView1.DataController.CreateAllItems;
  for i := 0 to cxGrid1DBTableView1.ColumnCount - 1 do
    cxGrid1DBTableView1.Columns[i].ApplyBestFit();
end;

This is a good start. Since I have no information from you, I can't get any closer.

Pang
  • 9,564
  • 146
  • 81
  • 122
Jens Borrisholt
  • 6,174
  • 1
  • 33
  • 67