11

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"
Mikael Eriksson
  • 132,594
  • 21
  • 199
  • 273
Banana
  • 136
  • 1
  • 1
  • 7

3 Answers3

19

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;
Remy Lebeau
  • 505,946
  • 29
  • 409
  • 696
  • How does that code then choose whether to pick the second or the first vehicle? – Shaun Roselt Jan 30 '17 at 09:14
  • 2
    @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 `` element. Now the structure of the XML has been changed, so the code needs to be adjusted accordingly. I have updated my answer. – Remy Lebeau Jan 30 '17 at 20:44
  • 1
    @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. – Remy Lebeau Jul 05 '19 at 16:14
6

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;
Toon Krijthe
  • 51,960
  • 37
  • 141
  • 201
  • 2
    Have a look at Delphi's own `TXMLDocument` wrapper component instead of accessing the `MSXML` engine directly. – Remy Lebeau Nov 11 '11 at 20:07
-1

smses count="1" backup_set="b8ea1116-9614-41d0-ac5b-ef93c27089cd" backup_date="1605468953370" type="full">