代码之家  ›  专栏  ›  技术社区  ›  Remus Rigo

xml中的xml示例/应用程序设置

  •  5
  • Remus Rigo  · 技术社区  · 16 年前

    有谁能帮助我学习如何使用XML吗。作为一个测试,我想用XML而不是INI文件来保存程序设置。

    8 回复  |  直到 16 年前
        1
  •  10
  •   Community Mohan Dere    9 年前

    里戈,你可以用 IXMLDocument 接口或 TXMLDocument

    您可以查看这些链接以获取有关XML和Delphi的更多信息

    查看此示例代码,了解使用 IXML文档

    program Delphi_XmlSaveSettings;
    
    {$APPTYPE CONSOLE}
    uses
      ActiveX,
      SysUtils,
      XmlDoc,
      XmlIntf;
    //this class mimic the basics functionalities of an TIniFile
    //you can improve a lot the code adding exception handling and more methods for specifics tasks.
    type
      TXMLSettings = class 
      private
        FFileName: string;
        FXMLDoc: IXMLDocument; //Main XMLObject
      public
        constructor Create(const FileName: string); overload;
        destructor  Destroy; override;
        function    ReadString(const Section, Key, default: string): string;
        procedure   WriteString(const Section, Key, Value: string);
        function    ReadInteger(const Section, Key: string; default: Integer): Integer;
        procedure   WriteInteger(const Section, Key: string; Value: Integer);
        function    ReadBoolean(const Section, Key: string; default: Boolean): Boolean;
        procedure   WriteBoolean(const Section, Key: string; Value: Boolean);
        function    ReadDouble(const Section, Key: string; default: Double): Double;
        procedure   WriteDouble(const Section, Key: string; Value: Double);
        function    ReadDateTime(const Section, Key: string; default: TDatetime): TDateTime;
        procedure   WriteDatetime(const Section, Key: string; Value: TDatetime);
        function    ReadDate(const Section, Key: string; default: TDatetime): TDateTime;
        procedure   WriteDate(const Section, Key: string; Value: TDatetime);
        procedure   Save;
      end;
    
    
    
    constructor TXMLSettings.Create(const FileName: string);
    begin
      inherited Create;
      FFileName       := FileName;
      FXMLDoc         := NewXMLDocument; //Create  aNew instance of a XML Document
      FXMLDoc.Encoding:= 'UTF-8'; //Set the encoding
      FXMLDoc.Options := [doNodeAutoIndent];//optional, is used to indent the Xml document
    
      if FileExists(FFileName) then
        FXMLDoc.LoadFromFile(FFileName)
      else
        FXMLDoc.AddChild('Root'); //Create the root Node
    end;
    
    
    destructor TXMLSettings.Destroy;
    begin
      Save;
      inherited;
    end;
    
    function TXMLSettings.ReadBoolean(const Section, Key: string; default: Boolean): Boolean;
    begin
      Result := Boolean(ReadInteger(Section, Key, Integer(default)));
    end;
    
    function TXMLSettings.ReadDate(const Section, Key: string; default: TDatetime): TDateTime;
    begin
      Result := StrToDate(ReadString(Section, Key, DateToStr(default)));
    end;
    
    function TXMLSettings.ReadDateTime(const Section, Key: string; default: TDatetime): TDateTime;
    begin
      Result := StrToDateTime(ReadString(Section, Key, DateTimeToStr(default)));
    end;
    
    function TXMLSettings.ReadDouble(const Section, Key: string;  default: Double): Double;
    begin
      Result := StrToFloat(ReadString(Section, Key, FloatToStr(default)));
    end;
    
    function TXMLSettings.ReadInteger(const Section, Key: string; default: Integer): Integer;
    begin
      Result := StrToInt(ReadString(Section, Key, IntToStr(default)));
    end;
    
    function TXMLSettings.ReadString(const Section, Key, default: string): string; 
    var
      XMLNode: IXMLNode;
    begin
      XMLNode := FXMLDoc.DocumentElement.ChildNodes.FindNode(Section);
      if Assigned(XMLNode) and XMLNode.HasAttribute(Key) then //Check if exist the Key
        Result := XMLNode.Attributes[Key]
      else
        Result := default;
    end;
    
    procedure TXMLSettings.Save;
    begin
      FXMLDoc.SaveToFile(FFileName);
    end;
    
    procedure TXMLSettings.WriteBoolean(const Section, Key: string; Value: Boolean);
    begin
      WriteInteger(Section, Key, Integer(Value));
    end;
    
    procedure TXMLSettings.WriteDate(const Section, Key: string; Value: TDatetime);
    begin
      WriteString(Section, Key, DateToStr(Value));
    end;
    
    procedure TXMLSettings.WriteDatetime(const Section, Key: string;  Value: TDatetime);
    begin
      WriteString(Section, Key, DateTimeToStr(Value));
    end;
    
    procedure TXMLSettings.WriteDouble(const Section, Key: string; Value: Double);
    begin
      WriteString(Section, Key, FloatToStr(Value));
    end;
    
    procedure TXMLSettings.WriteInteger(const Section, Key: string; Value: Integer);
    begin
      WriteString(Section, Key, IntToStr(Value));
    end;
    
    procedure TXMLSettings.WriteString(const Section, Key, Value: string);
    var
      XMLNode: IXMLNode;
    begin
      XMLNode := FXMLDoc.DocumentElement.ChildNodes.FindNode(Section);
      if not Assigned(XMLNode) then
      XMLNode := FXMLDoc.DocumentElement.AddChild(Section);
      XMLNode.Attributes[Key] := Value;
    end;
    
    
    Procedure SaveSettings; //Store the settings
    Var
      AppSettings :  TXMLSettings;
    begin
      AppSettings:=TXMLSettings.Create(ExtractFilePath(ParamStr(0))+'MySettings.xml');
      try
       AppSettings.WriteString('Server','Type','SQLServer');
       AppSettings.WriteString('Server','User','root');
       AppSettings.WriteInteger('Server','port',1433);
       AppSettings.WriteString('Server','IP','192.168.1.1');
       AppSettings.WriteString('Server','Database','Prod');
       AppSettings.WriteBoolean('Server','WindowsAuth',False);
       AppSettings.WriteDouble('Server','Latency',25.90892);
       AppSettings.WriteDatetime('Server','LastAccess',Now);
       AppSettings.WriteDate('Server','ActualDate',Now);
       AppSettings.Save;
      finally
      AppSettings.Free;
      end;
      Writeln('Settings Saved');
    end;
    
    
    Procedure ShowSettings;//Read the settings
    Var
      AppSettings :  TXMLSettings;
    begin
      AppSettings:=TXMLSettings.Create(ExtractFilePath(ParamStr(0))+'MySettings.xml');
      try
       Writeln(Format('Type         %s',[AppSettings.ReadString('Server','Type','')]));
       Writeln(Format('Port         %d',[AppSettings.ReadInteger('Server','port',0)]));
       Writeln(Format('IP           %s',[AppSettings.ReadString('Server','IP','')]));
       Writeln(Format('Database     %s',[AppSettings.ReadString('Server','Database','')]));
       Writeln(Format('WindowsAuth  %s',[BoolToStr(AppSettings.ReadBoolean('Server','WindowsAuth',True),True)]));
       Writeln(Format('Latency      %g',[AppSettings.ReadDouble('Server','Latency',0)]));
       Writeln(Format('LastAccess   %s',[DateTimeToStr(AppSettings.ReadDateTime('Server','LastAccess',Now-1))]));
       Writeln(Format('ActualDate   %s',[DateToStr(AppSettings.ReadDate('Server','ActualDate',Now-1))]));
      finally
      AppSettings.Free;
      end;
    end;
    
    begin
      try
        CoInitialize(nil); //only necesary in console applications
        try
          SaveSettings; //Save the sample settings
          ShowSettings; //Read the stored settings
          Readln;
        finally
        CoUninitialize; //only necesary in console applications
        end;
      except
        on E:Exception do
          Writeln(E.Classname, ': ', E.Message);
      end;
    end.
    
        2
  •  3
  •   Runner    16 年前

    我想RRUZ差不多都搞定了。

    你也可以看看 SimpleStorage 因为它是在这样的任务下做的。我用它来操作我所有的程序设置。例如,下面是我使用的一个示例(您可以看到它简化了代码,因为您不需要检查节点或值是否存在):

    XML:

    <Settings>
      <Service>
        <Name>*********</Name>
        <DisplayName>*********</DisplayName>
        <Description>************</Description>
      </Service>
      <Http>
        <ListenQueue>1000</ListenQueue>
        <Port>8778</Port>
      </Http>  
      <IPC>
        <Name>*******</Name>
      </IPC>
      <Modules>
        <Default>
          <Protocol>ISAPI</Protocol>
          <MaxProcNum>5</MaxProcNum>
          <MemoryLimit>500</MemoryLimit>
        </Default>
      </Modules>
    </Settings>
    

    procedure THydraSettings.LoadSettings(const RootPath: string);
    var
      Settings: ISimpleStorage;
      DefaulNode: IElement;
      DefExtDir: string;
    begin
      DefExtDir := ExtractFilePath(ParamStr(0)) + DIR_EXTENSIONS;
    
      Settings := StorageFromFile(RootPath + XML_SettingsFile);
      FExtensionsDir := Settings.Get(cNode_Extensions).AsStringDef(DefExtDir);
      FExtensionsDir := IncludeTrailingPathDelimiter(FExtensionsDir);
    
      // IPC server based settings
      FIPC.Name := Settings.Get(cNode_IPCName).AsStringDef('AI_Hydra');
    
      // http server based settings
      FHTTP.ServerPort := Settings.Get(cNode_HttpPort).AsIntegerDef(80);
      FHTTP.ListenQueue := Settings.Get(cNode_ListenQueue).AsIntegerDef(100);
    
      // get the defaults settings for modules
      DefaulNode := Settings.Get([cNode_Modules, cNode_Default]);
      FProtocol := DefaulNode.Get(cNode_Protocol).AsStringDef('ISAPI');
      FMaxProcNum := DefaulNode.Get(cNode_MaxProcNum).AsIntegerDef(5);
      FMemoryLimit := DefaulNode.Get(cNode_MemoryLimit).AsIntegerDef;
      FTimeout := DefaulNode.Get(cNode_MemoryLimit).AsIntegerDef(30);
      FUnload := DefaulNode.Get(cNode_Unload).AsBooleanDef;
    end;
    
        3
  •  2
  •   Alan Clark    16 年前

    在Delphi2009+的最新版本中,我相信有一个名为XMLIniFile的单元,它包含了一个名为TXMLIniFile和Txmlmeinifile的xml包装器。

        4
  •  2
  •   mjn anonym    15 年前

    开放源码 Jedi VCL 库包含 tjvappxmlfiles存储 类(单位为JvAppXMLStorage),将设置存储在XML文件中。

    TJvAppXMLFileStorage是一种数据存储 以XML格式存储数据的后端 文件。

    作为…的后代 TJvCustomAppXMLStorage它提供 存储数据的标准接口 (例如设置、窗体位置) 以及大小等)。 这些数据将存储在一个实际的 TJvSimpleXML对象的使用。

        5
  •  0
  •   Remy Lebeau    16 年前

    根据您使用的是哪个版本的Delphi,您可能有也可能没有可用的TXMLDocument组件。如果没有,则必须使用第三方XML库/组件。我更喜欢 libxml2

        6
  •  0
  •   G-Man    16 年前

    从瑞士中心

    http://www.swissdelphicenter.ch/torry/showcode.php?id=2269

    {This code shows how to use TXMLDocument to save and restore configuration
    settings in a XML document. The public methods works the same as a TIniFile.
    There is not mutch comment in the code because it is self explaining
    and small. Hope this benefit other persons. It is only tested in D7 pro.}
    
    unit uCiaXml;
    
    interface
    
    uses
      Forms, SysUtils, Windows, XmlIntf, XMLDoc;
    
    type
      TXMLConfig = class
      private
        FModified: Boolean;
        FFileName: string;
        FXMLDoc: TXMLDocument;
        FBackup: Boolean;
        function GetVersion: string;
      public
        constructor Create(const FileName: string); overload;
        constructor Create; overload;
        destructor Destroy; override;
        procedure Save;
        function ReadString(const Section, Key, default: string): string;
        procedure WriteString(const Section, Key, Value: string);
        function ReadInteger(const Section, Key: string; default: Integer): Integer;
        procedure WriteInteger(const Section, Key: string; Value: Integer);
        function ReadBoolean(const Section, Key: string; default: Boolean): Boolean;
        procedure WriteBoolean(const Section, Key: string; Value: Boolean);
        property Backup: Boolean read FBackup write FBackup;
        property Version: string read GetVersion;
      end;
    
    implementation
    
    { TXMLConfig }
    
    constructor TXMLConfig.Create(const FileName: string);
    begin
      inherited Create;
      FBackup         := True;
      FFileName       := FileName;
      FXMLDoc         := TXMLDocument.Create(Application);
      FXMLDoc.Options := [doNodeAutoIndent];
      if FileExists(FFileName) then
        FXMLDoc.LoadFromFile(FFileName)
      else 
      begin
        FXMLDoc.Active := True;
        FXMLDoc.AddChild('Configuration');
      end;
    end;
    
    constructor TXMLConfig.Create;
    begin
      Create(ChangeFileExt(Application.Exename, '_cfg.xml'));
    end;
    
    destructor TXMLConfig.Destroy;
    begin
      Save;
      FXMLDoc.Destroy;
      inherited;
    end;
    
    function TXMLConfig.GetVersion: string;
    begin
      Result := '1.00';
    end;
    
    function TXMLConfig.ReadBoolean(const Section, Key: string; default: Boolean): Boolean;
    begin
      Result := Boolean(ReadInteger(Section, Key, Integer(default)));
    end;
    
    function TXMLConfig.ReadInteger(const Section, Key: string; default: Integer): Integer;
    begin
      Result := StrToInt(ReadString(Section, Key, IntToStr(default)));
    end;
    
    function TXMLConfig.ReadString(const Section, Key, default: string): string;
    var
      Node: IXMLNode;
    begin
      Node := FXMLDoc.DocumentElement.ChildNodes.FindNode(Section);
      if Assigned(Node) and Node.HasAttribute(Key) then
        Result := Node.Attributes[Key]
      else
        Result := default;
    end;
    
    procedure TXMLConfig.Save;
    begin
      if not FModified then
        Exit;
      if FBackup then
    
        CopyFile(PChar(FFileName), PChar(FFileName + '.bak'), False);
      FXMLDoc.SaveToFile(FFileName);
      FModified := False;
    end;
    
    procedure TXMLConfig.WriteBoolean(const Section, Key: string; Value: Boolean);
    begin
      WriteInteger(Section, Key, Integer(Value));
    end;
    
    procedure TXMLConfig.WriteInteger(const Section, Key: string; Value: Integer);
    begin
      WriteString(Section, Key, IntToStr(Value));
    end;
    
    procedure TXMLConfig.WriteString(const Section, Key, Value: string);
    var
      Node: IXMLNode;
    begin
      if ReadString(Section, Key, '') = Value then
        Exit;
      Node := FXMLDoc.DocumentElement.ChildNodes.FindNode(Section);
      if not Assigned(Node) then
        Node := FXMLDoc.DocumentElement.AddChild(Section);
      Node.Attributes[Key] := Value;
      FModified := True;
    end;
    
    end.
    
        7
  •  0
  •   jachguate    16 年前

    要将配置存储在XML文件中,可以使用 OmniXML 图书馆。使用持久性衍生物非常简单:

    让我们说:

    type
      TConfig = class(TPersistent)
      private
        FSomeOption: string;
      published
        SomeOption: string read FSomeOption write FSomeOption;
      end;
    

    begin
      TOmniXMLWriter.SaveToFile(Config, ConfigFileName, pfNodes, ofIndent)
    end;
    

    其中Config是TConfig的实例。

    my blog (谷歌西班牙语翻译)

        8
  •  0
  •   menjaraz    14 年前

    VerySimpleXML 也可能适合这样的要求:配置文件的处理。