2010-09-10 15 views

Odpowiedz

10

Rigo, można użyć interfejsu IXMLDocument lub obiektu TXMLDocument do interakcji z dokumentem XML.

Można sprawdzić te linki, aby uzyskać więcej informacji na temat XML i Delphi

Odjazd ten przykładowy kod, aby nauczyć się podstaw o zarządzaniu xml przy użyciu interfejsu IXMLDocument.

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. 
+0

Jest to dobry przykład, ale tylko notatkę. Naśladujesz plik INI tutaj. Myślę, że moc XML nad INI polega na elastyczności XML i nieskończonej głębi, jaką możesz mieć. Dobry przykład inaczej :) – Runner

+0

@Runner, podaję tę próbkę w prosty sposób, aby użyć XML do zapisania ustawień aplikacji, oczywiście OP może zaimplementować bardziej elastyczne i złożone rozwiązanie, gdy zna XML w głębi. – RRUZ

0

zależności od edycja Delphi używasz, może lub nie może mieć składnik TXMLDocument dostępny. Jeśli tego nie zrobisz, będziesz musiał użyć biblioteki/składnika XML innej firmy. Ja sam wolę libxml2 i ma on powiązanie dostępne dla Pascal/Delphi.

3

Myślę, że RRUZ w większości ma wszystko.

Możesz również spojrzeć na SimpleStorage, ponieważ została stworzona właśnie z myślą o tym. Używam go do wszystkich manipulacji ustawieniami mojego programu. Na przykład tutaj jest jednym z takich przykładów używam (można go zobaczyć upraszcza kod bo nie trzeba by sprawdzić, czy węzeł lub wartość istnieją):

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> 

And The Kod:

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; 
2

W ostatnich wersjach Delphi, 2009+ wierzę, że jest to jednostka o nazwie XMLIniFile który zawiera opakowanie xml wokół TIniFile nazywa TXMLIniFile, a także TXMLMemIniFile.

Jednak w mojej instalacji Delphi 2010 XMLIniFile.pas brakuje i tylko XMLIniFile.dcu jest obecny, nadal można go używać oczywiście. Ponadto wydaje się być nieudokumentowanym, nawet w Docwiki Delphi.

0

Od swissdelphicenter

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. 
0

Aby zapisać konfigurację w pliku XML, można użyć biblioteki OmniXML.Jest to dość proste w użyciu pochodnych TPersistent:

powiedzmy:

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

następnie, z jednej linii kodu można zapisać go do pliku XML:

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

gdzie config instancja TConfig.

można przeczytać nieco więcej na ten temat w my blog (przetłumaczony z języka hiszpańskiego z Google)

pozdrawiam.

2

open source Jedi VCL biblioteka zawiera TJvAppXMLFileStorage klasę (w jednostkach JvAppXMLStorage), która przechowuje ustawienia w pliku XML.

TJvAppXMLFileStorage jest przechowywanie danych backend, który przechowuje dane w pliku XML .

Jako potomek TJvCustomAppXMLStorage Zapewnia standardowy interfejs do przechowywania danych (takie jak ustawienia, pozycjach formularza i rozmiarach, etc) w formacie XML . Dane te będą przechowywane w rzeczywistym pliku , reprezentowanym w pamięci przez użycie obiektu TJvSimpleXML.

0

VerySimpleXML może również spełniać takie wymagania: obsługa pliku konfiguracyjnego.

Ma niewielki rozmiar przede wszystkim.