Search code examples
xmldelphilazarus

How do I convert code between OmniXML and Delphi's own XML library?


I recently started using OmniXML primarily because it can be used for both Delphi and Lazarus.

I myself am a beginner when it comes to XML, and this is where I hope I can learn some things or avoid doing any bad things I may already be doing.

For this I am going to use another question I have as a reference: Saving and Loading Treeview using XML

In one of the answers by bummi, I think he is using standard XML in Delphi where I am using OmniXML in Lazarus, so the code he posted in his answer would not compile. I have it working now after changing some of the code but I need to know if the following is correct:


(1) Variable Types

Delphi

TTreeToXML = Class
private
  FDOC: TXMLDocument;
  FRootNode: IXMLNode;

OmniXML

TTreeToXML = Class
private
  FDOC: IXMLDocument;
  FRootNode: IXMLElement; 

(2) Creating the XML Document

Delphi

FDOC := TXMLDocument.Create(nil);

OmniXML

FDOC := CreateXMLDoc; 

(3) Freeing the XML Document

Delphi

if Assigned(FDOC) then
    FDOC.Free;

OmniXML

I cannot see a way to Free the document?


(4) Attributes

Delphi

Procedure TTreeToXML.WriteNode(N: TTreeNode; ParentXN: IXMLNode);
var
  CurrNode: IXMLNode;
  Child: TTreeNode;
begin
  CurrNode := ParentXN.AddChild(N.Text);
  CurrNode.Attributes['NodeLevel'] := N.Level;
  CurrNode.Attributes['Index'] := N.Index;
  Child := N.getFirstChild;
  while Assigned(Child) do
  begin
    WriteNode(Child, CurrNode);
    Child := Child.getNextSibling;
  end;
end;

OmniXML

Procedure TTreeToXML.WriteNode(N: TTreeNode; ParentXN: IXMLNode);
var
  CurrNode: IXMLNode;
  Child: TTreeNode;
begin
  CurrNode := ParentXN.AddChild(N.Text);
  CurrNode.Attributes.SetValue('NodeLevel', IntToStr(N.Level));
  CurrNode.Attributes.SetValue('NodeIndex', IntToStr(N.Index));
  Child := N.getFirstChild;
  while Assigned(Child) do
  begin
    WriteNode(Child, CurrNode);
    Child := Child.getNextSibling;
  end;
end; 

(5) Options

Delphi

FDOC.Options := FDOC.Options + [doNodeAutoIndent];

OmniXML

The Document is saved with indents automatically, I cannot find any options?


(6) Active

Delphi

FDOC.Active := true;

OmniXML

I see no way of setting such a property to True or False?


(7) Encoding

Delphi

FDOC.Encoding := 'UTF-8';

OmniXML

Again I see no such option?


So basically I guess I would like to know what are the differences between the Delphi XML and OmniXML implementations.

Are the changes I made the correct way of doing it or not?

The properties I cannot find such as Options and Encoding, how would I implement this in OmniXML?

Thanks.


Solution

  • (1) Variable Types

    TTreeToXML = Class
    private
      FDOC: IXMLDocument;
      FRootNode: IXMLNode; 
    

    (2) Creating the XML Document

    OK.

    (3) Freeing the XML Document

    No need to free. Its interface based. You can explicitly free it like this:

    FDOC := nil;
    

    provided you don't have any other references to it.

    (4) Attributes

    Probably OK. Did not look into it to much.

    (5) Options

    You control indentation when you save XML document.

    procedure TXMLDocument.Save(const FileName: string; const OutputFormat: TOutputFormat = ofNone);
    

    This is what the OutputFormat is for. Also check the "PreserveWhiteSpace" property when loading the XML from file or stream.

    (6) Active

    What is Active? I see no need for it.

    (7) Encoding

    Use:

    function CreateProcessingInstruction(const Target, Data: XmlString): IXMLProcessingInstruction;
    

    To write it like this for instance:

    <?xml version="1.0" encoding="UTF-8" ?>
    

    This is if you save the document and you want to specify the encoding. For reading OmniXML can read almost any encoding provided that the BOM is there.


    Anyway OmniXML is very similar to TXMLDocument. Changes are mostly in the programmers interface and OmniXML is compatible with MSXML.

    You can also check my SimpleStorage which is a set of interfaces on top of OmniXML that simplify it a LOT. Just check the demos and see what I mean. But it does not work under Lazarus unfortunately.