Lazarus

Programming => LCL => Topic started by: edgarrod71 on May 02, 2018, 11:53:32 am

Title: A better FindNode? XML is weak
Post by: edgarrod71 on May 02, 2018, 11:53:32 am
Hi, I tried to make a FindNode that searches deep inside a XMLDocument, it finds recursively but only finds the first <w:p> text, but it doesn't find if there are more... how can I fix this?

I attached the xml file, but for the example, here's part of the code of the XML:
Code: XML  [Select][+][-]
  1.       <w:r w:rsidRPr="00077AE0">
  2.         <w:rPr>
  3.           <w:rFonts w:ascii="Arial" w:hAnsi="Arial" w:cs="Arial"/>
  4.           <w:b/>
  5.           <w:sz w:val="16"/>
  6.           <w:szCs w:val="16"/>
  7.           <w:u w:val="single"/>
  8.         </w:rPr>         
  9.         <!--hola edgar-->        
  10.         <w:t>ЖАЛОБЫ</w:t>
  11.                 </w:r>
  12.       <w:r w:rsidRPr="00077AE0">
  13.         <w:rPr>
  14.           <w:rFonts w:ascii="Arial" w:hAnsi="Arial" w:cs="Arial"/>
  15.           <w:sz w:val="16"/>
  16.           <w:szCs w:val="16"/>
  17.         </w:rPr>
  18.         <w:t>____</w:t>
  19.       </w:r>
  20.       <w:r w:rsidR="005F1AD7" w:rsidRPr="00077AE0">
  21.         <w:rPr>
  22.           <w:rFonts w:ascii="Arial" w:hAnsi="Arial" w:cs="Arial"/>
  23.           <w:sz w:val="16"/>
  24.           <w:szCs w:val="16"/>
  25.           <w:u w:val="single"/>
  26.         </w:rPr>
  27.         <w:t>{[complaints]}</w:t>
  28.       </w:r>
  29.       <w:r w:rsidR="002107F6" w:rsidRPr="00077AE0">
  30.         <w:rPr>
  31.           <w:rFonts w:ascii="Arial" w:hAnsi="Arial" w:cs="Arial"/>
  32.           <w:sz w:val="16"/>
  33.           <w:szCs w:val="16"/>
  34.           <w:u w:val="single"/>
  35.         </w:rPr>
  36.         <w:tab/>
  37.       </w:r>
  38.       <w:r w:rsidR="002107F6" w:rsidRPr="00077AE0">
  39.         <w:rPr>
  40.           <w:rFonts w:ascii="Arial" w:hAnsi="Arial" w:cs="Arial"/>
  41.           <w:sz w:val="16"/>
  42.           <w:szCs w:val="16"/>
  43.           <w:u w:val="single"/>
  44.         </w:rPr>
  45.         <w:tab/>
  46.       </w:r>
  47.     </w:p>
  48.     <w:p w14:paraId="59228417" w14:textId="1BF8370E" w:rsidR="00346D56" w:rsidRPr="00077AE0" w:rsidRDefault="00346D56" w:rsidP="00F12AEB">
  49.       <w:pPr>
  50.         <w:tabs>
  51.           <w:tab w:val="right" w:leader="underscore" w:pos="9781"/>
  52.         </w:tabs>
  53.         <w:spacing w:line="288" w:lineRule="auto"/>
  54.         <w:ind w:left="-1077"/>
  55.         <w:jc w:val="both"/>
  56.         <w:rPr>
  57.           <w:rFonts w:ascii="Arial" w:hAnsi="Arial" w:cs="Arial"/>
  58.           <w:sz w:val="16"/>
  59.           <w:szCs w:val="16"/>
  60.         </w:rPr>
  61.       </w:pPr>
  62.       <w:r w:rsidRPr="00077AE0">
  63.         <w:rPr>
  64.           <w:rFonts w:ascii="Arial" w:hAnsi="Arial" w:cs="Arial"/>
  65.           <w:b/>
  66.           <w:sz w:val="16"/>
  67.           <w:szCs w:val="16"/>
  68.           <w:u w:val="single"/>
  69.         </w:rPr>
  70.         <w:t>АНАМНЕЗ</w:t>
  71.       </w:r>


Here's my recursive function, I made a helper for TDOMNode_WithChildren:
Code: Pascal  [Select][+][-]
  1. function TSearchNode.FindNode(const aNodeName: DOMString;
  2.     aNodeContent: DOMString; const aNode: TDOMNode): TDOMNode;
  3. var S: String;  /// these two variables are for debugging only... so you can skip them
  4.     T: String;
  5.  
  6.     function NodeFound(var Node: TDOMNode): boolean;
  7.     var vNode: TDOMNode;
  8.         bName: boolean;
  9.     begin
  10.        result := false;
  11.        if Node = nil then exit;
  12.  
  13.        bName := Node.CompareName(aNodeName)=0;
  14.        if bName then begin
  15.          if UTF8CompareStr(Node.TextContent, aNodeContent)=0 then begin
  16.              result := true;
  17.              exit;
  18.            end;
  19.        end;
  20.  
  21.        vNode := Node.FirstChild;
  22.  
  23.        if assigned(vNode) then begin
  24.            S := vNode.NodeName;
  25.            T := vNode.TextContent;
  26.        end;
  27.  
  28.        while assigned(vNode) and not result do begin
  29.            result := NodeFound(vNode);
  30.            S := vNode.NodeName;
  31.            T := vNode.TextContent;
  32.            if result then begin
  33.              Node := vNode;  /// we must take the value out
  34.              break;
  35.            end;
  36.            vNode := vNode.NextSibling;
  37.            if assigned(vNode) then begin
  38.                S := vNode.NodeName;
  39.                T := vNode.TextContent;
  40.            end;
  41.        end;
  42.     end;
  43.  
  44. begin
  45.    if assigned(aNode) then begin
  46.      S := aNode.NodeName;
  47.      T := aNode.TextContent;
  48.    end;
  49.     if aNode = nil then
  50.       result := FFirstChild
  51.     else
  52.     if aNode.NextSibling = nil then
  53.       result := aNode.ParentNode.NextSibling
  54.     else
  55.       result := aNode.NextSibling;
  56.     while assigned(result) do begin
  57.         S := result.NodeName;
  58.         T := result.TextContent;
  59.         if NodeFound(result) then
  60.           break;
  61.         result := result.NextSibling;
  62.         if assigned(result) then begin
  63.             S := result.NodeName;
  64.             T := result.TextContent;
  65.         end;
  66.     end;
  67. end;
  68.  
TinyPortal © 2005-2018