Recent

Author Topic: Lazarus and XML  (Read 2182 times)

paweld

  • Hero Member
  • *****
  • Posts: 1268
Re: Lazarus and XML
« Reply #15 on: October 01, 2023, 11:25:46 pm »
I prefer to process xml files using SAX. Any extension is much simpler. The only condition is that you must know the file format.

Sample project in attachment.
Best regards / Pozdrawiam
paweld

wp

  • Hero Member
  • *****
  • Posts: 12464
Re: Lazarus and XML
« Reply #16 on: October 01, 2023, 11:50:49 pm »
My solution uses XPath to simplify finding the starting nodes for each query. Once such a node has been found the required information is extracted by climbing down the subtrees similar to my previous post. At first I am traversing the pracownicy tree, some information is stored in a list for easier lookup later. In the same way budynek tree could be traversed (which I didn't do). Finally I am traversing the cyklDydaktyczny tree collecting the information of some subnodes. The prowadzacy ref is replaced by the associated name in the list prepared earlier. Finally the results are written to screen.
Code: Pascal  [Select][+][-]
  1. program project1;
  2.  
  3. {$mode objfpc}{$h+}
  4.  
  5. uses
  6.   SysUtils, fgl,
  7.   laz2_dom, laz2_xmlread, laz2_xpath;
  8.  
  9. const
  10.   XML_FILE_NAME = 'plan.xml';
  11.  
  12. type
  13.   TNameList = specialize TFPGMap<string, string>;
  14.  
  15. var
  16.   XPathResult: TXPathVariable;
  17.   XMLDocument: TXMLDocument;
  18.   ns: TNodeSet;
  19.   i, j: Integer;
  20.   rootNode: TDOMNode;
  21.   pracownicyNode, grupaNode, spotkanieNode: TDOMNode;
  22.   nodeName: String;
  23.   idStr, imieStr, nazwiskoStr: String;
  24.   numerStr, typStr: String;
  25.   dataStr, godzinaOdStr, godzinaDoStr, prowadzacyRefStr, pracownicyStr: String;
  26.   pracownicyList: TNameList;
  27.  
  28. begin
  29.   pracownicyList := TNameList.Create;
  30.   pracownicyList.Sorted := true;
  31.  
  32.   ReadXMLFile(XMLDocument, XML_FILE_NAME);
  33.   rootNode := XMLDocument.DocumentElement;
  34.  
  35.   XPathResult := EvaluateXPathExpression('/plan/pracownicy', rootNode);
  36.   ns := XPathResult.AsNodeSet;
  37.   for i := 0 to ns.Count-1 do
  38.   begin
  39.     pracownicyNode := TDOMNode(ns[i]);
  40.     if pracownicyNode.HasChildNodes then
  41.     begin
  42.       pracownicyNode := pracownicyNode.FirstChild;
  43.       while Assigned(pracownicyNode) do
  44.       begin
  45.         nodeName := pracownicyNode.NodeName;
  46.         if nodeName = 'pracownik' then
  47.         begin
  48.           idStr := pracownicyNode.Attributes.GetNamedItem('id').NodeValue;
  49.           imieStr := pracownicyNode.FindNode('imie').TextContent;
  50.           nazwiskoStr := pracownicyNode.FindNode('nazwisko').TextContent;
  51.         end;
  52.         WriteLn(idStr, ' --> ', imieStr, ' ', nazwiskoStr);
  53.         pracownicyList.Add(idStr, imieStr + ' ' + nazwiskoStr);
  54.         pracownicyNode := pracownicyNode.NextSibling;
  55.       end;
  56.     end;
  57.   end;
  58.   XPathResult.Free;
  59.  
  60.   WriteLn;
  61.   WriteLn('numer', #9, 'typ', #9, 'data', #9, 'godzinaOd', #9, 'godzinaDo', #9, 'imie nazwisko');
  62.  
  63.   XPathResult := EvaluateXPathExpression('/plan/cykleDydaktyczne/cyklDydaktyczny/przedmiot/grupaZajeciowa', rootNode);
  64.   ns := XPathResult.AsNodeSet;
  65.   for i:=0 to ns.Count-1 do
  66.   begin
  67.     grupaNode := TDOMNode(ns[i]);
  68.     nodeName := grupaNode.NodeName;
  69.     numerStr := grupaNode.FindNode('numer').TextContent;
  70.     typStr := grupaNode.FindNode('typ').TextContent;
  71.     spotkanieNode := grupaNode.FindNode('spotkanie');
  72.     while spotkanieNode <> nil do
  73.     begin
  74.       nodeName := spotkanieNode.NodeName;
  75.       if nodeName = 'spotkanie' then
  76.       begin
  77.         dataStr := spotkanieNode.FindNode('data').TextContent;
  78.         godzinaOdStr := spotkanieNode.FindNode('godzinaOd').TextContent;
  79.         godzinaDoStr := spotkanieNode.FindNode('godzinaDo').TextContent;
  80.         prowadzacyRefStr := spotkanieNode.FindNode('prowadzacy').Attributes.GetNamedItem('ref').NodeValue;
  81.         if pracownicyList.Find(prowadzacyRefStr, j) then
  82.           pracownicyStr := pracownicyList.Data[j] + ' (' + prowadzacyRefStr + ')'
  83.         else
  84.           pracownicyStr := '(' + prowadzacyRefStr + ')';
  85.         WriteLn(numerStr, #9, typStr, #9, dataStr, #9, godzinaOdStr, #9, godzinaDoStr, #9, pracownicyStr);
  86.       end;
  87.       spotkanieNode := spotkanieNode.NextSibling;
  88.     end;
  89.   end;
  90.  
  91.   XPathResult.Free;
  92.   XMLDocument.Free;
  93.   pracownicyList.Free;
  94. end.  
« Last Edit: October 02, 2023, 12:09:58 am by wp »

 

TinyPortal © 2005-2018