How to read data from xml file and display it over the text box in delphi language
Asked Answered
C

3

13

I am new to the delphi language, and here I have a doubt, I have a xml file called vehicle.xml.

It looks like this

<data>
<vehicle>
    <type>Car</type>
    <model>2005</model>
    <number>1568</number>
</vehicle>
<vehicle>
    <type>Car</type>
    <model>2009</model>
    <number>1598</number>
</vehicle>
</data>

My Delphi form contains three text boxes:

  • txtType
  • txtModel
  • txtnumber

While loading the page I want to display the contents of the vehicle.xml over the text box like:

  • txtType=Car
  • txtModel=2005
  • txtNumber="1568"
Cammi answered 11/11, 2011 at 6:51 Comment(0)
D
21

Have a look at Delphi's own TXMLDocument component, for example:

uses
  ..., XMLIntf, XMLDoc;

procedure TForm1.FormCreate(Sender: TObject);
var
  Vehicle: IXMLNode;
begin
  XMLDocument1.FileName :='vehicle.xml';
  XMLDocument1.Active := True;
  try
    Vehicle := XMLDocument.DocumentElement;
    txtType.Text := Vehicle.ChildNodes['type'].Text;
    txtModel.Text := Vehicle.ChildNodes['model'].Text;
    txtnumber.Text  := Vehicle.ChildNodes['number'].Text;
  finally
    XMLDocument1.Active := False;
  end;
end;

Alternatively, use the IXMLDocument interface directly (which TXMLDocument implements):

uses
  ..., XMLIntf, XMLDoc;

procedure TForm1.FormCreate(Sender: TObject);
var
  Doc: IXMLDocument;
  Vehicle: IXMLNode;
begin
  Doc := LoadXMLDocument('vehicle.xml');
  Vehicle := Doc.DocumentElement;
  txtType.Text := Vehicle.ChildNodes['type'].Text;
  txtModel.Text := Vehicle.ChildNodes['model'].Text;
  txtnumber.Text := Vehicle.ChildNodes['number'].Text;
end;

Update: the XML in the question has been altered to now wrap the vehicle element inside of a data element, and to have multiple vehicle elements. So the code above has to be adjusted accordingly, eg:

uses
  ..., XMLIntf, XMLDoc;

procedure TForm1.FormCreate(Sender: TObject);
var
  Doc: IXMLDocument;
  Data: IXMLNode;
  Node: IXMLNode;
  I: Integer;
begin
  Doc := LoadXMLDocument('vehicle.xml');
  Data := Doc.DocumentElement;
  for I := 0 to Data.ChildNodes.Count-1 do
  begin
    Node := Data.ChildNodes[I];
    // if all of the child nodes will always be 'vehicle' only
    // then this check can be removed...
    if Node.LocalName = 'vehicle' then
    begin
      // use Node.ChildNodes['type'], Node.ChildNodes['model'],
      // and Node.ChildNodes['number'] as needed...
    end;
  end;
end;
Drainpipe answered 11/11, 2011 at 20:12 Comment(3)
How does that code then choose whether to pick the second or the first vehicle?Class
@ShaunRoselt: the XML in the question was altered after I had posted this answer. This answer was written for different XML where the top-level element was the only <vehicle> element. Now the structure of the XML has been changed, so the code needs to be adjusted accordingly. I have updated my answer.Drainpipe
@MarceloBergweiler seriously? It is time like this that I wish I could downvote comments. Drop a TXMLDocument into the Form and the uses clause is filled in automatically, like any other component. But whatever. I've updated my answer.Drainpipe
S
7

You can read the XML file using the unit MSXML (or any other XML parser).

It gives you a tree structure representing the XML file. Where vehicle is the top node and the other three are the child nodes.

Each node has a text property that can be used to get the value. You can assign that to the text boxes on your form.

Code sample:

uses
  ActiveX,
  MSXML;

procedure TForm1.ReadFromXML(const AFilename: string);
var
  doc : IXMLDOMDocument;
  node : IXMLDomNode;

begin
  CoInitialize; // Needs to be called once before using CoDOMDocument.Create;
  if not FileExists(AFileName) then 
    Exit; // Add proper Error handling.

  doc := CoDOMDocument.Create;
  doc.load(AFileName);

  if (doc.documentElement = nil) or (doc.documentElement.nodeName <> 'vehicle') then
    Exit; // Add proper Error handling.

  node := doc.documentElement.firstChild;
  while node<>nil do begin
    if node.nodeName = 'model' then
      txtModel.Text := node.text;
    if node.nodeName = 'number' then
      txtNumber.Text := node.text;
    if node.nodeName = 'type' then
      txtType.Text := node.text;
    node := node.nextSibling;
  end;
end;
Secretin answered 11/11, 2011 at 7:6 Comment(1)
Have a look at Delphi's own TXMLDocument wrapper component instead of accessing the MSXML engine directly.Drainpipe
M
2

I wrote a library to manage XML files, it uses IXMLDocument interface to load the XML data from file or string, you can check it here.

To read multiple nodes you can do this:

uses
  .., IXMLData;

procedure TForm1.cxButton1Click(Sender: TObject);
var
  d : TIXMLDoc;
  i : integer;
begin
  d := TIXMLDoc.CreateFromFile('vehicle.xml');
  for i := 0 to d.childcount - 1 do
  begin
    //Here you get the different node values
    txtType.Text := d.Text(d.ChildNodes[i], 'type');
    txtModel.Text := d.Text(d.ChildNodes[i], 'model');
    txtType.Text :=d.Text(d.ChildNodes[i], 'number');
  end;
end;
Macmullin answered 17/3, 2023 at 18:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.