将列表框数据保存为 XML? [英] Saving Listbox Data to XML?

查看:17
本文介绍了将列表框数据保存为 XML?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 2 个列表框,第一个列表框存储每个项目 Object 属性的数据指针(由我编写的自定义类定义).每当我从这个列表框中选择一个项目时,我都会通过访问存储在第一个列表框中的一些数据来填充第二个列表框.

I have 2 listboxes, the first listbox stores data pointers for each items Object property (defined by a custom class I have written). Whenever I select an item from this listbox, I populate the second listbox by accessing some of the data stored on the first listbox.

这很好,但现在我需要知道如何将列表框保存和恢复为 XML.

That is all good, but now I need to know how to save and restore the listboxes to XML.

如果有人可以提供示例或帮助我编写代码来执行此操作,我将不胜感激.

I would appreciate it if someone could provide an example or assist me in writing the code to do this.

以下是一些示例代码,展示了我如何创建和访问数据:

Here is some sample code to show how I create and access the data:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    ListBox2: TListBox;
    cmdAdd: TButton;
    txtValue1: TEdit;
    txtValue2: TEdit;
    procedure cmdAddClick(Sender: TObject);
    procedure ListBox1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

type
  TMyData = class(TObject)
  private
    FValue1: String;
    FValue2: String;
  public
    constructor Create(Value1, Value2: String);

    property Value1: String read FValue1 write FValue1;
    property Value2: String read FValue2 write FValue2;
end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TMyData }

constructor TMyData.Create(Value1, Value2: String);
begin
  inherited Create;

  FValue1:= Value1;
  FValue2:= Value2;
end;

procedure TForm1.cmdAddClick(Sender: TObject);
var
  Obj: TMyData;
begin
  Obj:= TMyData.Create(txtValue1.Text, txtValue2.Text);
  Listbox1.AddItem(txtValue1.Text, Obj);
end;

procedure TForm1.ListBox1Click(Sender: TObject);
var
  Obj: TMyData;
begin
  ListBox2.Items.Clear;

  Obj:= ListBox1.Items.Objects[ListBox1.ItemIndex] as TMyData;
  ListBox2.Items.Add(Obj.Value2);
end;

end.

推荐答案

tl;dr: 使用 XML 数据绑定 向导创建用于处理特定 XML 文件的接口,等等.

tl;dr: Use the XML Data Binding wizard to create interfaces for handling your specific XML file, ét voila.

最简单的实现方法是从 XML 文件开始.例如,如下构建它:

The most easy way to implement this is to start with the XML file. For example, build it up as follows:

<?xml version="1.0"?>
<masteritems>
    <masteritem>
        <name>Caption1</name>
        <value>123456</value>
        <childitems>
            <childitem>
                <name>Caption1.1</name>
                <value>23452</value>
            </childitem>
            <childitem>
                <name>Caption1.2</name>
                <value>65465</value>
            </childitem>
        </childitems>
    </masteritem>
    <masteritem>
        ...
    </masteritem>
</masteritems>

接下来,使用 XML 数据绑定向导为这种类型的 XML 文件创建一个接口单元,请参阅 文件 > 新建 > 其他 > 新建 > XML 数据绑定.随心所欲地进行调整,但默认情况下只需通过单击确定"来传递每个向导页面就可以了.(请注意,其他 Delphi 版本的默认设置可能与我的不同.)虽然我个人喜欢摆脱的一件事是每个接口类型的类型"后缀.(以及类类型名称,但这不是向导中的选项,因此您可以手动进行.)

Next, create an interface unit for this type of XML file by using the XML Data Binding Wizard, see File > New > Other > New > XML Data Binding. Tweak as you like, but simply passing every wizard page by clicking OK works just fine by default. (Note that the default settings for other Delphi versions might differ from that of mine.) Though the one thing I personally like to get rid of is the "Type" suffix for every interface type. (As well as for the class type names, but that's not an option in the wizard, so you might do that manually.)

现在,加载和操作这个 XML 文件:

And now, to load and manipulate this XML file:

uses
  Classes, Controls, Forms, StdCtrls,
  Test, xmldom, XMLIntf, msxmldom, XMLDoc;

type
  TForm2 = class(TForm)
    ListBox1: TListBox;
    ListBox2: TListBox;
    XMLDocument1: TXMLDocument; { See tab 'Internet' on component palette }
    SaveButton: TButton;
    procedure FormCreate(Sender: TObject);
    procedure ListBox1Click(Sender: TObject);
    procedure SaveButtonClick(Sender: TObject);
  private
    function CurrentMasterItem: IXMLMasterItem;
  end;

...

function TForm2.CurrentMasterItem: IXMLMasterItem;
var
  MasterItems: IXMLMasterItems;
  I: Integer;
begin
  MasterItems := GetMasterItems(XMLDocument1);
  for I := 0 to MasterItems.Count - 1 do
  begin
    Result := MasterItems.Masteritem[I];
    if Result.Name = ListBox1.Items[ListBox1.ItemIndex] then
      Break;
  end;
end;

procedure TForm2.FormCreate(Sender: TObject);
var
  MasterItems: IXMLMasterItems;
  I: Integer;
begin
  XMLDocument1.FileName := 'Test.xml';
  XMLDocument1.NodeIndentStr := '<tab>';
  MasterItems := GetMasterItems(XMLDocument1);
  for I := 0 to MasterItems.Count - 1 do
    ListBox1.Items.Add(MasterItems[I].Name);
  XMLDocument1.Active := False;
end;

procedure TForm2.ListBox1Click(Sender: TObject);
var
  ChildItems: IXMLChildItems;
  I: Integer;
begin
  if ListBox1.ItemIndex > -1 then
  begin
    ChildItems := CurrentMasterItem.Childitems;
    ListBox2.Clear;
    for I := 0 to ChildItems.Count - 1 do
      ListBox2.Items.AddObject(ChildItems[I].Name,
        TObject(ChildItems[I].Value));
    XMLDocument1.Active := False;
  end;
end;

procedure TForm2.SaveButtonClick(Sender: TObject);
var
  ChildItems: IXMLChildItems;
  ChildItem: IXMLChildItem;
  I: Integer;
begin
  if ListBox1.ItemIndex > -1 then
  begin
    ListBox2.Items.AddObject('New item', TObject(543223));
    ChildItems := CurrentMasterItem.Childitems;
    ChildItems.Clear;
    for I := 0 to ListBox2.Count - 1 do
    begin
      ChildItem := ChildItems.Add;
      ChildItem.Name := ListBox2.Items[I];
      ChildItem.Value := Integer(ListBox2.Items.Objects[I]);
    end;
    XMLDocument1.SaveToFile(XMLDocument1.FileName);
    XMLDocument1.Active := False;
  end;
end;

更新:这是向导在此处创建的单元:

Update: This is the unit the wizard created here:

{*********************************************************}
{                                                         }
{                    XML Data Binding                     }
{                                                         }
{         Generated on: 10-11-2011 23:25:30               }
{       Generated from: H:DelphiTestXMLTestTest.xml   }
{   Settings stored in: H:DelphiTestXMLTestTest.xdb   }
{                                                         }
{*********************************************************}

unit Test;

interface

uses xmldom, XMLDoc, XMLIntf;

type

{ Forward Decls }

  IXMLMasterItems = interface;
  IXMLMasterItem = interface;
  IXMLChildItems = interface;
  IXMLChildItem = interface;

{ IXMLMasterItems }

  IXMLMasterItems = interface(IXMLNodeCollection)
    ['{ACA35986-053A-40AE-92E8-2044BC5DADC6}']
    { Property Accessors }
    function Get_Masteritem(Index: Integer): IXMLMasterItem;
    { Methods & Properties }
    function Add: IXMLMasterItem;
    function Insert(const Index: Integer): IXMLMasterItem;
    property Masteritem[Index: Integer]: IXMLMasterItem
      read Get_Masteritem; default;
  end;

{ IXMLMasterItem }

  IXMLMasterItem = interface(IXMLNode)
    ['{E6481675-AE5B-4166-A977-CA29EC97B78D}']
    { Property Accessors }
    function Get_Name: WideString;
    function Get_Value: Integer;
    function Get_Childitems: IXMLChildItems;
    procedure Set_Name(Value: WideString);
    procedure Set_Value(Value: Integer);
    { Methods & Properties }
    property Name: WideString read Get_Name write Set_Name;
    property Value: Integer read Get_Value write Set_Value;
    property Childitems: IXMLChildItems read Get_Childitems;
  end;

{ IXMLChildItems }

  IXMLChildItems = interface(IXMLNodeCollection)
    ['{CD16D91C-30E5-45A1-AAA1-1C518C84EA5B}']
    { Property Accessors }
    function Get_Childitem(Index: Integer): IXMLChildItem;
    { Methods & Properties }
    function Add: IXMLChildItem;
    function Insert(const Index: Integer): IXMLChildItem;
    property Childitem[Index: Integer]: IXMLChildItem
      read Get_Childitem; default;
  end;

{ IXMLChildItem }

  IXMLChildItem = interface(IXMLNode)
    ['{F7399037-A33F-4E43-ADF9-000EAD71B418}']
    { Property Accessors }
    function Get_Name: WideString;
    function Get_Value: Integer;
    procedure Set_Name(Value: WideString);
    procedure Set_Value(Value: Integer);
    { Methods & Properties }
    property Name: WideString read Get_Name write Set_Name;
    property Value: Integer read Get_Value write Set_Value;
  end;

{ Forward Decls }

  TXMLMasteritemsType = class;
  TXMLMasteritemType = class;
  TXMLChilditemsType = class;
  TXMLChilditemType = class;

{ TXMLMasteritemsType }

  TXMLMasteritemsType = class(TXMLNodeCollection, IXMLMasterItems)
  protected
    { IXMLMasterItems }
    function Get_Masteritem(Index: Integer): IXMLMasterItem;
    function Add: IXMLMasterItem;
    function Insert(const Index: Integer): IXMLMasterItem;
  public
    procedure AfterConstruction; override;
  end;

{ TXMLMasteritemType }

  TXMLMasteritemType = class(TXMLNode, IXMLMasterItem)
  protected
    { IXMLMasterItem }
    function Get_Name: WideString;
    function Get_Value: Integer;
    function Get_Childitems: IXMLChildItems;
    procedure Set_Name(Value: WideString);
    procedure Set_Value(Value: Integer);
  public
    procedure AfterConstruction; override;
  end;

{ TXMLChilditemsType }

  TXMLChilditemsType = class(TXMLNodeCollection, IXMLChildItems)
  protected
    { IXMLChildItems }
    function Get_Childitem(Index: Integer): IXMLChildItem;
    function Add: IXMLChildItem;
    function Insert(const Index: Integer): IXMLChildItem;
  public
    procedure AfterConstruction; override;
  end;

{ TXMLChilditemType }

  TXMLChilditemType = class(TXMLNode, IXMLChildItem)
  protected
    { IXMLChildItem }
    function Get_Name: WideString;
    function Get_Value: Integer;
    procedure Set_Name(Value: WideString);
    procedure Set_Value(Value: Integer);
  end;

{ Global Functions }

function Getmasteritems(Doc: IXMLDocument): IXMLMasterItems;
function Loadmasteritems(const FileName: WideString): IXMLMasterItems;
function Newmasteritems: IXMLMasterItems;

const
  TargetNamespace = '';

implementation

{ Global Functions }

function Getmasteritems(Doc: IXMLDocument): IXMLMasterItems;
begin
  Result := Doc.GetDocBinding('masteritems',
    TXMLMasteritemsType, TargetNamespace) as IXMLMasterItems;
end;

function Loadmasteritems(const FileName: WideString): IXMLMasterItems;
begin
  Result := LoadXMLDocument(FileName).GetDocBinding('masteritems',
    TXMLMasteritemsType, TargetNamespace) as IXMLMasterItems;
end;

function Newmasteritems: IXMLMasterItems;
begin
  Result := NewXMLDocument.GetDocBinding('masteritems',
    TXMLMasteritemsType, TargetNamespace) as IXMLMasterItems;
end;

{ TXMLMasteritemsType }

procedure TXMLMasteritemsType.AfterConstruction;
begin
  RegisterChildNode('masteritem', TXMLMasteritemType);
  ItemTag := 'masteritem';
  ItemInterface := IXMLMasterItem;
  inherited;
end;

function TXMLMasteritemsType.Get_Masteritem(Index: Integer): IXMLMasterItem;
begin
  Result := List[Index] as IXMLMasterItem;
end;

function TXMLMasteritemsType.Add: IXMLMasterItem;
begin
  Result := AddItem(-1) as IXMLMasterItem;
end;

function TXMLMasteritemsType.Insert(const Index: Integer): IXMLMasterItem;
begin
  Result := AddItem(Index) as IXMLMasterItem;
end;

{ TXMLMasteritemType }

procedure TXMLMasteritemType.AfterConstruction;
begin
  RegisterChildNode('childitems', TXMLChilditemsType);
  inherited;
end;

function TXMLMasteritemType.Get_Name: WideString;
begin
  Result := ChildNodes['name'].Text;
end;

procedure TXMLMasteritemType.Set_Name(Value: WideString);
begin
  ChildNodes['name'].NodeValue := Value;
end;

function TXMLMasteritemType.Get_Value: Integer;
begin
  Result := ChildNodes['value'].NodeValue;
end;

procedure TXMLMasteritemType.Set_Value(Value: Integer);
begin
  ChildNodes['value'].NodeValue := Value;
end;

function TXMLMasteritemType.Get_Childitems: IXMLChildItems;
begin
  Result := ChildNodes['childitems'] as IXMLChildItems;
end;

{ TXMLChilditemsType }

procedure TXMLChilditemsType.AfterConstruction;
begin
  RegisterChildNode('childitem', TXMLChilditemType);
  ItemTag := 'childitem';
  ItemInterface := IXMLChildItem;
  inherited;
end;

function TXMLChilditemsType.Get_Childitem(Index: Integer): IXMLChildItem;
begin
  Result := List[Index] as IXMLChildItem;
end;

function TXMLChilditemsType.Add: IXMLChildItem;
begin
  Result := AddItem(-1) as IXMLChildItem;
end;

function TXMLChilditemsType.Insert(const Index: Integer): IXMLChildItem;
begin
  Result := AddItem(Index) as IXMLChildItem;
end;

{ TXMLChilditemType }

function TXMLChilditemType.Get_Name: WideString;
begin
  Result := ChildNodes['name'].Text;
end;

procedure TXMLChilditemType.Set_Name(Value: WideString);
begin
  ChildNodes['name'].NodeValue := Value;
end;

function TXMLChilditemType.Get_Value: Integer;
begin
  Result := ChildNodes['value'].NodeValue;
end;

procedure TXMLChilditemType.Set_Value(Value: Integer);
begin
  ChildNodes['value'].NodeValue := Value;
end;

end.

这篇关于将列表框数据保存为 XML?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆