如何在Delphi语言中从XML文件中读取数据并在文本框中显示

12

我是Delphi语言的新手,我有一个疑问,我有一个名为vehicle.xml的xml文件。

它看起来像这样

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

我的 Delphi 表单包含三个文本框:

  • txtType
  • txtModel
  • txtnumber

在加载页面时,我希望像以下这样在文本框上显示 vehicle.xml 文件的内容:

  • txtType=Car
  • txtModel=2005
  • txtNumber="1568"
4个回答

20

例如,可以看一下 Delphi 自带的 TXMLDocument 组件:

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;

或者直接使用 TXMLDocument 实现的 IXMLDocument 接口:

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;

更新:问题中的XML已经被修改,现在将vehicle元素包裹在一个data元素中,并且有多个vehicle元素。因此,上面的代码必须相应地进行调整,例如:

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;

那段代码是如何选择是选第二个还是第一个车辆的呢? - Shaun Roselt
2
@ShaunRoselt:在我发布这个答案之后,问题中的XML已经被修改了。这个答案是针对不同的XML编写的,其中顶层元素是唯一的<vehicle>元素。现在XML的结构已经改变,因此代码需要相应地进行调整。我已经更新了我的答案。 - Remy Lebeau
1
@MarceloBergweiler 真的吗?就是在这种时候,我希望我能够对评论进行踩。只需将 TXMLDocument 拖放到窗体中,uses 子句就会自动填充,就像其他任何组件一样。但无论如何,我已经更新了我的答案。 - Remy Lebeau

6
你可以使用MSXML单元(或任何其他XML解析器)来读取XML文件。
它会给你一个表示XML文件的树状结构,其中vehicle是顶级节点,另外三个是子节点。
每个节点都有一个文本属性,可以用于获取值。你可以将其分配到表单上的文本框中。
代码示例:
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;

2
不要直接访问MSXML引擎,而是看一下Delphi自己的TXMLDocument包装器组件。 - Remy Lebeau

1

我编写了一个管理XML文件的库,它使用IXMLDocument接口从文件或字符串中加载XML数据,您可以在这里检查它。

要读取多个节点,您可以这样做:

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;

-1

短信计数="1" 备份集="b8ea1116-9614-41d0-ac5b-ef93c27089cd" 备份日期="1605468953370" 类型="完整">


1
嗨,Trang,你提交的答案并没有为解决 OP 的问题做出贡献。 - Matt G

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接