XML-使用 Lazarus freepascal 的 RPC

XML-RPC with Lazarus freepascal

我知道有很多 freepascal xml 教程和帖子,但到目前为止我发现的任何东西似乎都不适合我。 我正在构建 Lazarus 桌面应用程序以通过 API 连接到 Odoo,获取一些数据、处理和响应。 xml 响应的结构很难处理(至少对我而言)。 示例响应是:

<?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>

问题是这些值没有唯一标签或 ID。 我想做的是通过名称访问值。我面临的问题是值等没有 ID,有些部分是数组。 我一直在尝试

variables:= Doc.DocumentElement.GetElementsByTagName('member');
fname:=variables[3].FindNode('value').TextContent;

但是如果结构发生变化并且没有真正考虑数组,这将失败。 任何帮助将不胜感激。

毕竟我自己找到了答案。感谢任何贡献者。 我知道这是否不是最优雅的方式,但它可以完成工作。 我通过 xml 分隔函数 运行,onc 返回字符串,另一个数组。

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');
    for c:=0 to myNodes.Count-1 do
     begin
      Name:= myNodes[c].FindNode('name').TextContent;
        if (Name=searchvar) then begin
         try
          subNodes:= myNodes[c].GetChildNodes;
          subNodes:= subNodes[1].GetChildNodes;
          subNodes:= subNodes[0].GetChildNodes;
          subNodes:= subNodes[0].GetChildNodes;
          v:=0;
          SetLength(Result, subNodes.Count);
           for v:=0 to subNodes.Count-1 do
            begin
             Result[v]:= subNodes[v].TextContent;
            end;

          finally
           subNodes.Free;
          end;
         end;
       end;
  finally
  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');
   for c:=0 to myNodes.Count-1 do
    begin
    Name:= myNodes[c].FindNode('name').TextContent;
     if (Name=searchvar) then begin
      result:= myNodes[c].FindNode('value').TextContent;
     end;
   end;
  finally
  myNodes.Free;
  end;
end;