Fabrizio
Fabrizio

Reputation: 8043

How to extract a subnode value from XML text?

I'm trying to extract the value of a sub node named left, which is inside a node named design but an EInvalidPointer occurs.

I'm using Delphi 2007 and this is the XML text:

<design>
  <top>
    0
  </top>
  <left>
    5
  </left>
  <height>
    177
  </height>
  <width>
    130
  </width>
</design>

And this is the code:

uses
  XMLDoc, XMLIntf...

var                  
  Stream : TStream;
  Doc : TXMLDocument;
  Node : IXMLNode;
begin
  Stream := TStringStream.Create(Memo1.Lines.Text);
  try
    Doc := TXMLDocument.Create(nil);
    try
      Doc.LoadFromStream(Stream);
      Node := Doc.ChildNodes.FindNode('design');
      if(Node <> nil) then
      begin
        Node := Node.ChildNodes.FindNode('left'); //EInvalidPointer here
        if(Node <> nil) then
        begin
          //...
        end;
      end;
    finally
      Doc.Free;
    end;
  finally
    Stream.Free;
  end;
end;

Could someone help me understanding what I'm doing wrong?

Upvotes: 1

Views: 394

Answers (1)

David Heffernan
David Heffernan

Reputation: 612794

Doc := TXMLDocument.Create(nil);

When you pass nil to the constructor of TXMLDocument that means that you are asking for the lifetime to be managed by reference counting. Which means that you need to declare Doc as an interface reference:

var
  Doc: IXMLDocument;

Naturally when you do this you do not call Free on Doc, and the try/finally block can be removed. Reference counting of interfaces is automatically managed by code that the compiler emits on your behalf.

If you want to use a class reference, as your code is currently configured, you would need to pass an owner to the constructor.

Upvotes: 2

Related Questions