Как прочитать данные из xml-файла и отобразить их в текстовом поле на языке delphi

#delphi #delphi-2009

#delphi #delphi-2009

Вопрос:

Я новичок в языке delphi, и здесь у меня есть сомнения, у меня есть XML-файл под названием vehicle.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″

Ответ №1:

Взгляните, например, на собственный TXMLDocument компонент Delphi:

 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;
  

В качестве альтернативы, используйте IXMLDocument интерфейс напрямую (который TXMLDocument реализует):

 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;
  

Комментарии:

1. Как этот код затем выбирает, выбрать ли второе или первое транспортное средство?

2. @ShaunRoselt: XML в вопросе был изменен после того, как я опубликовал этот ответ. Этот ответ был написан для другого XML, где элемент верхнего уровня был единственным <vehicle> элементом. Теперь структура XML была изменена, поэтому код необходимо соответствующим образом скорректировать. Я обновил свой ответ.

3. @MarceloBergweiler серьезно? Вот в такое время я хотел бы отказаться от комментариев. Поместите TXMLDocument в форму, и uses предложение заполнится автоматически, как и любой другой компонент. Но неважно. Я обновил свой ответ.

Ответ №2:

Вы можете прочитать XML-файл, используя модуль MSXML (или любой другой анализатор XML).

Это дает вам древовидную структуру, представляющую XML-файл. Где vehicle — это верхний узел, а остальные три — дочерние узлы.

У каждого узла есть свойство text, которое можно использовать для получения значения. Вы можете назначить это текстовым полям в вашей форме.

Пример кода:

 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;
  

Комментарии:

1. Взгляните на собственный компонент- TXMLDocument оболочку Delphi вместо прямого доступа к MSXML движку.

Ответ №3:

Я написал библиотеку для управления 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;