delphi - XML-RPC with Lazarus freepascal -
i know there plenty of freepascal xml tutorials , posts, nothing found far seem job me. building lazarus desktop app connect through api odoo, data, process , respond. structure of xml response quite difficult (at least me) work with. example response is:
<?xml version='1.0'?> <methodresponse> <params> <param> <value> <array> <data> <value> <struct> <member> <name>create_date</name> <value> <string>2016-03-30 09:05:23</string> </value> </member> <member> <name>file_name</name> <value> <string>o156ap000100</string> </value> </member> <member> <name>dispatch_date</name> <value> <string>2016-04-04</string> </value> </member> <member> <name>height</name> <value> <int>0</int> </value> </member> <member> <name>custom_option_mapping_ids</name> <value> <array> <data /> </array> </value> </member> <member> <name>message_ids</name> <value> <array> <data /> </array> </value> </member> <member> <name>message_summary</name> <value> <string /> </value> </member> <member> <name>create_uid</name> <value> <array> <data> <value> <int>7</int> </value> <value> <string>my 1st years</string> </value> </data> </array> </value> </member> <member> <name>display_name</name> <value> <string>artwork.job,283</string> </value> </member> <member> <name>message_is_follower</name> <value> <boolean>1</boolean> </value> </member> <member> <name>production_date</name> <value> <boolean>0</boolean> </value> </member> <member> <name>message_last_post</name> <value> <boolean>0</boolean> </value> </member> <member> <name>id</name> <value> <int>283</int> </value> </member> <member> <name>width</name> <value> <int>0</int> </value> </member> <member> <name>file_path</name> <value> <string>2016-04-04/table rate/1</string> </value> </member> <member> <name>text_colour</name> <value> <array> <data> <value> <int>489</int> </value> <value> <string>text colour: fuchsia pink</string> </value> </data> </array> </value> </member> <member> <name>text_lines</name> <value> <array> <data> <value> <int>1686</int> </value> <value> <int>16380</int> </value> </data> </array> </value> </member> <member> <name>sale_order_id</name> <value> <array> <data> <value> <int>368</int> </value> <value> <string>so156</string> </value> </data> </array> </value> </member> <member> <name>text_font</name> <value> <array> <data> <value> <int>492</int> </value> <value> <string>font: verdana</string> </value> </data> </array> </value> </member> </struct> </value> </data> </array> </value> </param> </params> </methodresponse>
the problem values without unique tags, or id's. trying access values names. problem facing there no id's values etc, , parts arrays. have been trying
variables:= doc.documentelement.getelementsbytagname('member'); fname:=variables[3].findnode('value').textcontent;
but fail if structure changes , doesn't take arrays account. appreciated.
after have found answer myself. thx contributed. know if it's not elegant way of doing this, job though. made separate functions running through xml, onc returning string, other 1 array.
type tstringarray = array of string; ... public function extractvar(doc1: txmldocument; searchvar:string): string; function extractarray(doc1: txmldocument; searchvar:string): tstringarray; ... var textlines: tstringarray; ... function tathread.extractarray(doc1: txmldocument; searchvar:string): tstringarray; var c,v:integer; name,value:string; mynodes: tdomnodelist; subnodes: tdomnodelist; begin c:=0; try mynodes:= doc1.documentelement.getelementsbytagname('member'); c:=0 mynodes.count-1 begin name:= mynodes[c].findnode('name').textcontent; if (name=searchvar) begin try subnodes:= mynodes[c].getchildnodes; subnodes:= subnodes[1].getchildnodes; subnodes:= subnodes[0].getchildnodes; subnodes:= subnodes[0].getchildnodes; v:=0; setlength(result, subnodes.count); v:=0 subnodes.count-1 begin result[v]:= subnodes[v].textcontent; end; subnodes.free; end; end; end; mynodes.free; end; end; function tathread.extractvar(doc1: txmldocument; searchvar:string): string; var c:integer; name:string; mynodes: tdomnodelist; begin c:=0; try mynodes:= doc1.documentelement.getelementsbytagname('member'); c:=0 mynodes.count-1 begin name:= mynodes[c].findnode('name').textcontent; if (name=searchvar) begin result:= mynodes[c].findnode('value').textcontent; end; end; mynodes.free; end; end;