2

I want to write some code (in Delphi) to get this XML scheme, I tried but no result as I want, could you help me ! I use (or want use) IXMLDocument created at runtime, but I can't understand "Nodes", "ChildNodes" ... I know, it's ridiculous !

This is the scheme example I want :

<Items>
 <Task id="eec0-47de-91bc-98e2d69d75cd">
   <Title>The title of something</Title>
   <State>Done</State>
   <IdNoHashed>This Is a string</IdNoHashed>
   <CreatedDate>28/12/2011 06:24:57</CreatedDate>
   <Note>Just a note</Note>
 </Task>
 <Task id="e2x5d4-2d45c-98e2d69d75cd">
   <Title>Another title</Title>
   <State>Done</State>
   <IdNoHashed>This Is a string 2</IdNoHashed>
   <CreatedDate>28/12/2011 22:22:22</CreatedDate>
   <Note>Just a note, again !</Note>
 </Task>
</items>

Do you have a suggestion ? Thank you !

EDIT : I Tried the code answered below, It works fine, but when I want to add any other entry in the Root, it rewrites the already-exist element.

Function WriteData (id, title, state, idNH : String) : Boolean;
 var
   Doc: IXMLDocument;
   Items, Task: IXMLNode;
begin
  Doc := NewXMLDocument;
  Items := Doc.AddChild('Items');

  Task := Items.AddChild('Task');
  Task.Attributes['id'] := id;
  Task.AddChild('Title').Text := title;
  Task.AddChild('State').Text := state;
  Task.AddChild('IdNoHashed').Text := idNH;
  Task.AddChild('CreatedDate').Text := DateTimeToStr(Now);
  Task.AddChild('Note').Text := 'Just a note';
end;

I tried DocumentElement.ChildNodes.FindNode(id), but not success !

I created a function which I call each time to add/modify an entry in the XML file, the entry is "". An idea to how can I do this ?! Thank you !

djiga4me
  • 345
  • 1
  • 4
  • 13

2 Answers2

12

Check this sample application which uses the IXMLDocument interface, the comments in the source explains how the elements are added

{$APPTYPE CONSOLE}

{$R *.res}

uses
  ActiveX,
  XMLIntf,
  XMLDoc,
  SysUtils;

procedure Test;
Var
  XML : IXMLDocument;
  RootNode, Node, CNode : IXMLNode;
begin
  XML := NewXMLDocument;//initializate the interface
  XML.Options := [doNodeAutoIndent];//activate the auto indentation
  RootNode := XML.AddChild('Items');//add the root node
  Node := RootNode.AddChild('Task');//add the task node
  Node.Attributes['id'] := 'eec0-47de-91bc-98e2d69d75cd';//<Task id="eec0-47de-91bc-98e2d69d75cd">
   CNode:=Node.AddChild('Title');//add the title node
   CNode.Text:='The title of something';//<Title>The title of something</Title>
   CNode:=Node.AddChild('State');//add the State node
   CNode.Text:='Done'; //<State>Done</State>
   CNode:=Node.AddChild('IdNoHashed');//add the IdNoHashed node
   CNode.Text:='This Is a string'; //<IdNoHashed>This Is a string</IdNoHashed>
   CNode:=Node.AddChild('CreatedDate');//add the CreatedDate node
   CNode.Text:=FormatDateTime('dd/mm/yyyy hh:nn:ss',EncodeDate(2011,12,28)+EncodeTime(6,24,57,0));//<CreatedDate>28/12/2011 06:24:57</CreatedDate>
   CNode:=Node.AddChild('Note');//Add the Note node
   CNode.Text:='Just a note'; //<Note>Just a note</Note>

  //repeat the process again for the second task node    
  Node := RootNode.AddChild('Task');
  Node.Attributes['id'] := 'e2x5d4-2d45c-98e2d69d75cd';
   CNode:=Node.AddChild('Title');
   CNode.Text:='Another title';
   CNode:=Node.AddChild('State');
   CNode.Text:='Done';
   CNode:=Node.AddChild('IdNoHashed');
   CNode.Text:='This Is a string 2';
   CNode:=Node.AddChild('CreatedDate');
   CNode.Text:=FormatDateTime('dd/mm/yyyy hh:nn:ss',EncodeDate(2011,12,28)+EncodeTime(22,22,22,0));
   CNode:=Node.AddChild('Note');
   CNode.Text:='Just a note, again !';

  Writeln(XML.XML.Text); //Show the output
end;


begin
 try
    CoInitialize(nil); //use this just in console apps
    try
      Test;
    finally
      CoUninitialize;//use this just in console apps
    end;
 except
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
 Writeln('Press Enter to exit');
 Readln;
end.
RRUZ
  • 134,889
  • 20
  • 356
  • 483
  • thank you so much, for the accuracy too, and for the comment, I finally understant things ! Thank you !! – djiga4me Dec 28 '11 at 17:06
7

Like this:

var
  Doc: IXMLDocument;
  Items, Task: IXMLNode;
begin
  Doc := NewXMLDocument;
  Items := Doc.AddChild('Items');

  Task := Items.AddChild('Task');
  Task.Attributes['id'] := 'eec0-47de-91bc-98e2d69d75cd';
  Task.AddChild('Title').Text := 'The title of something';
  Task.AddChild('State').Text := 'Done';
  Task.AddChild('IdNoHashed').Text := 'This Is a string';
  Task.AddChild('CreatedDate').Text := DateTimeToStr(Now);
  Task.AddChild('Note').Text := 'Just a note';

  Task := Items.AddChild('Task');
  Task.Attributes['id'] := 'e2x5d4-2d45c-98e2d69d75cd';
  Task.AddChild('Title').Text := 'Another title';
  Task.AddChild('State').Text := 'Done';
  Task.AddChild('IdNoHashed').Text := 'This Is a string 2';
  Task.AddChild('CreatedDate').Text := DateTimeToStr(Now);
  Task.AddChild('Note').Text := 'Just a note, again!';

// save Doc as needed...
// Doc.SaveToStream(...);
// Doc.SaveToFile(...);
// Doc.SaveToXML(...);
// XML := Doc.XML.Text; 
// etc...

end;

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thank you, it's simple, (just add as Doc.Options:=[doNodeAutoIndent]) to Indent things! I will use this for the ease ! – djiga4me Dec 28 '11 at 17:08