I try to find a node with specific "node name", "attribute" and "attribute value". I use the recursive function below.

My XMLDocument has a node named 'TestNodeName' with attribute 'Format' with value '1'.

The function works fine the first time: returns the prower node.  

When I call it a second time, it gives wrong results: returns a node that has a Format attribute having value 0.

Example of XML. 

```
<mnode>
  <TestNodeName ID="1" Format="0">
  </TestNodeName>
  <TestNodeName ID="2" Format="1">
  </TestNodeName>
  <TestNodeName ID="3" Format="0">
  </TestNodeName>
  <TestNodeName ID="4" Format="1">
  </TestNodeName>
  <TestNodeName ID="5" Format="0">
  </TestNodeName>
</mnode>

```

End of XML

```
unit Unit4;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, XMLIntf, XMLDoc;

type
  TForm4 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
//GLOBAL VARIABLES
var
  Form4: TForm4;
  XML:IXMLDocument;
  mnode:IXMLNode;
  s:string;
implementation

{$R *.dfm}
function RecursiveFindNode(ANode: IXMLNode; const SearchNodeName: string): IXMLNode;
var
  I: Integer;
begin
  if CompareText(ANode.NodeName, SearchNodeName) = 0 then
    Result := ANode
  else if not Assigned(ANode.ChildNodes) then
    Result := nil
  else begin
    for I := 0 to ANode.ChildNodes.Count - 1 do
    begin
      Result := RecursiveFindNode(ANode.ChildNodes[I], SearchNodeName);
      if Assigned(Result) then
        Exit;
    end;
  end;
end;

function RecursiveFindNodeAttr(ANode: IXMLNode; const SearchNodeName: string; sAttr, sAttrVal:string): IXMLNode;
var
  I: Integer;
  sAttrFind: ixmlnode;
  stext:string;
begin
  sAttrFind:=ANode.AttributeNodes.FindNode(sAttr);
  if sAttrFind<>nil then stext:=sAttrFind.Text else stext:='';
  if (CompareText(ANode.NodeName, SearchNodeName)=0)and(CompareText(sAttrFind.NodeName, sAttr)=0)and(CompareText(stext, sAttrVal)=0) then
  begin
    Result := ANode;
  end
  else if not Assigned(ANode.ChildNodes) then
  begin
    Result := nil;
  end
  else begin
    for I := 0 to ANode.ChildNodes.Count - 1 do
    begin
      Result := RecursiveFindNodeAttr(ANode.ChildNodes[I], SearchNodeName, sAttr, sAttrVal);
      if Assigned(Result) then
      begin
        Exit;
      end;
    end;
  end;
end;

procedure TForm4.FormCreate(Sender: TObject);
var
cnode,foundNode:IXMLNode; //<-- Problem here "foundNode" must be in global 
begin
XML:= NewXMLDocument;
XML.LoadFromFile('C:\test.xml');
mnode:=XML.DocumentElement;
foundNode:=RecursiveFindNode(mnode,'TestNodeName');

//First time
cnode:=RecursiveFindNodeAttr(XML.DocumentElement,'TestNodeName','Format','1');
if cnode<>nil then
begin
cnode.Attributes['Format']:='5';
ShowMessage('ID='+cnode.Attributes['ID']);
end
else
ShowMessage('nil');

//Second time
foundNode:=RecursiveFindNodeAttr(XML.DocumentElement,'TestNodeName','Format','1');
if foundNode<>nil then
begin
foundNode.Attributes['Format']:='5';
ShowMessage('ID='+foundNode.Attributes['ID']);
end
else
ShowMessage('nil');

XML.SaveToFile('C:\test.xml');

end;

end.

```

After few test i finally found what caused wrong result of function. There was a similar recursive function. When i removed call of function all result was OK.
 RecursiveFindNode(ANode: IXMLNode; const SearchNodeName: string): IXMLNode;

In code bellow is call 
 foundNode:=RecursiveFindNode(mnode,'TestNodeName');
The first call of RecursiveFindNodeAttr will give good result because of "cnode:="
The second call of RecursiveFindNodeAttr will give wrong result (ID=1) because i used same variable "foundNode:=RecursiveFindNodeAttr(..."

Finally when i moved "var foundNode:IXMLNode;" from Tform4 declaration to global the second call returned good result (ID=4)

I found another problem. when i use RecursiveFindNodeAttr in loop after replace all format="1" to format="5", the "foundNode" result remains "not nil" so loop will never end. 

```
foundNode:=RecursiveFindNodeAttr(XML.DocumentElement,'TestNodeName','Format','1');
while foundNode<>nil do
begin
    foundNode.Attributes['Format']:='5';
    ShowMessage('ID='+foundNode.Attributes['ID']);

foundNode:=RecursiveFindNodeAttr(XML.DocumentElement,'TestNodeName','Format','1');
if foundNode=nil then ShowMessage('nil');
end;

```