w3hello.com logo
Home PHP C# C++ Android Java Javascript Python IOS SQL HTML videos Categories
Delphi XML Recursive function, search a node with specific attribute value

It seems "if not Assigned(ANode.ChildNodes) then" is always assigned. when i changed it to "if not (ANode.HasChildNodes) then" it stopped loop forever. I added into function messages to display how exactly is function executed.

It seems it checks same node 2 times, 1st time in "if (CompareText(ANode.Node..." and second time in loop "for I := 0 to ANode.ChildNo...".

<mnode UID="main">
  <TestNodeName UID="1" Format="5">
    <TestNodeName UID="11" Format="5">
    </TestNodeName>
    <TestNodeName UID="12" Format="5">
    </TestNodeName>
    <TestNodeName UID="13" Format="5">
    </TestNodeName>
  </TestNodeName>
  <TestNodeName UID="2" Format="5">
  </TestNodeName>
  <TestNodeName UID="3" Format="5">
    <TestNodeName UID="31" Format="5">
    </TestNodeName>
    <TestNodeName UID="32" Format="5">
      <TestNodeName UID="321" Format="1">
      </TestNodeName>
      <TestNodeName UID="322" Format="5">
      </TestNodeName>
      <TestNodeName UID="323" Format="1">
      </TestNodeName>
    </TestNodeName>
    <TestNodeName UID="33" Format="5">
    </TestNodeName>
  </TestNodeName>
  <TestNodeName UID="4" Format="5">
  </TestNodeName>
</mnode>

function RecursiveFindNodeAttr(ANode: IXMLNode; const
SearchNodeName: string; sAttr, sAttrVal:string): IXMLNode;
var
  I: Integer;
begin
  if (CompareText(ANode.NodeName,
SearchNodeName)=0)and(ANode.Attributes[sAttr]=sAttrVal) then
  begin
    ShowMessage('Found! '+ANode.Attributes['UID']);
    Result := ANode;
  end
  else
    begin
    ShowMessage('1st try='+ANode.Attributes['UID']);
    if not (ANode.HasChildNodes) then
    begin
    ShowMessage('nil');
    Result := nil;
    end
  else begin
    for I := 0 to ANode.ChildNodes.Count - 1 do
     begin
      Result := RecursiveFindNodeAttr(ANode.ChildNodes[I], SearchNodeName,
sAttr, sAttrVal);
      ShowMessage('loop='+ANode.ChildNodes[I].Attributes['UID']);
      if Assigned(Result) then
      begin
        ShowMessage('found in
loop='+ANode.ChildNodes[I].Attributes['UID']);
        Exit;
      end;
     end;
    end;
   end;
end;

var
  XML:IXMLDocument;
  mnode,cnode:IXMLNode;

begin

XML:= NewXMLDocument;
XML.LoadFromFile('C:	est.xml');
mnode:=XML.DocumentElement;

//This will replace all Format="1" to Format="0"
cnode:=RecursiveFindNodeAttr(mnode,'TestNodeName','Format','1');
while cnode<>nil do
begin
  cnode.Attributes['Format'] := '0';
  ShowMessage(cnode.Attributes['UID']);
  cnode:=RecursiveFindNodeAttr(mnode,'TestNodeName','Format','1');
end;
if cnode= nil  then
ShowMessage('cnode= nil ');

end.




© Copyright 2018 w3hello.com Publishing Limited. All rights reserved.