Lazarus

Programming => General => Topic started by: michoux on August 05, 2020, 09:37:56 am

Title: XML read
Post by: michoux on August 05, 2020, 09:37:56 am
I have following xml.

********************************************************
<?xml version="1.0" encoding="utf-8"?>
<Canoe123 System="Main">
  <Schedule>
    <Race Race="K1-Men Ht 1.Run" Order="1" RaceId="K1M_NHT1_22" SubTitle="1st Run" MainTitle="Kayak (K1) Men" RaceStatus="3" ShortTitle="K1-Men Ht 1.Run">
      <StartTime/>
    </Race>
    <Race Race="C2-Men Ht 1.Run" Order="2" RaceId="C2M_NHT1_22" SubTitle="1st Run" MainTitle="Canoe Double (C2) Men" RaceStatus="0" ShortTitle="C2-Men Ht 1.Run">
      <StartTime/>
    </Race>
  </Schedule>
</Canoe123>
********************************************************


I want to parse it but I have problems accessing even the Race node from XML
For example
********************************************************
procedure TFMain.Button11Click(Sender: TObject);
var doc: TXMLDocument;
 node: TDOMNode;
 begin

    ReadXMLFile(Doc, 'c:\tv\schedule.xml');
    node := Doc.DocumentElement.Findnode('Race');
    showmessage(node.NodeName);
end;     
********************************************************
Above gives sigserv error.
If I search for Schedule node it is ok.
Title: Re: XML read
Post by: Jurassic Pork on August 05, 2020, 10:19:18 am
hello,
to search multiple nodes anywhere in an xml, you can use xpath  with //.
Example to search all the nodes Race in your xml file and to display the RaceId attributes :
Code: Pascal  [Select][+][-]
  1.  // ...
  2. uses DOM, XMLRead, XMLWrite, XPath;
  3. // ...
  4. procedure TForm1.Bt_GoClick(Sender: TObject);
  5. var
  6.   Xml: TXMLDocument;
  7.   XPathResult: TXPathVariable;
  8.   TheNodeSet : TNodeSet;
  9.   i: integer;
  10. begin
  11.   try
  12.   ReadXMLFile(Xml,'canoe.xml');
  13.   // Find Nodes with tag Race
  14.   XPathResult := EvaluateXPathExpression('//Race', Xml.DocumentElement);
  15.   TheNodeSet := XPathResult.AsNodeSet;
  16.   if TheNodeSet.Count > 0 then
  17.     begin
  18.         For i := 0 to TheNodeSet.Count - 1 do
  19.           begin
  20.             Memo1.Append('Result : ' +
  21.                          TDomElement(TheNodeSet.Items[i]).AttribStrings['RaceId']);
  22.           end;
  23.     end;
  24.   XPathResult.Free;
  25.   finally
  26.   Xml.Free;
  27.   end;  
  28.  
  29. end;          
  30.  

Result :
Quote
Result : K1M_NHT1_22
Result : C2M_NHT1_22

Friendly, J.P
Title: Re: XML read
Post by: michoux on August 05, 2020, 11:28:39 am
Perfect :)

What if I have 2 nodes which I want to query
I need to check participant and result

For example:

<Row Number="1">
      <Participant Id="637281647486932019" Bib="   1" Nat="" Club="KKK Ljubljana" Name="HAJDINJAK Eva" GivenName="Eva" StartTime="16:00:00" FamilyName="Hajdinjak" StartOrder="1"/>
      <Result Q="Q" PP="" IRM="" Pen="0" Rank="1" Time="1.00" Type="T" Gates="  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0" Total="1.00" Behind="" HeatNr="0" RankOrder="1"/>
    </Row>
    <Row Number="2">
      <Participant Id="637281647486932020" Bib="   2" Nat="" Club="KKK SE" Name="TURK Zarja" GivenName="Zarja" StartTime="16:00:30" FamilyName="Turk" StartOrder="2"/>
      <Result Q="Q" PP="" IRM="" Pen="0" Rank="1" Time="1.00" Type="T" Gates="  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0" Total="1.00" Behind="" HeatNr="0" RankOrder="2"/>
    </Row>

Then I guess I need to first go to row and then work with nextsibling
Title: Re: XML read
Post by: michoux on August 05, 2020, 12:55:21 pm
I found it
  XPathResult := EvaluateXPathExpression('//Participant | //Result, Xml.DocumentElement);
Title: Re: XML read
Post by: zoltanleo on August 05, 2020, 10:42:35 pm
Hi michoux.

Try to use GetElementsByTagName (https://lazarus-ccr.sourceforge.io/docs/lazutils/laz2_dom/tdomdocument.getelementsbytagname.html) function. You may read xml-tutorial (https://wiki.lazarus.freepascal.org/XML_Tutorial) or use  search (https://forum.lazarus.freepascal.org/index.php/topic,39432.msg270619.html#msg270619) for examples also.
TinyPortal © 2005-2018