如何在Perl中循环遍历SOAP :: Lite响应的子数组?

时间:2015-03-31 14:01:40

标签: perl soap soaplite

我有一个成功获取ShoreTel电话服务器响应的Perl脚本。服务器提供有关所输入分机当前连接的呼叫的信息。但是,当有多个项目时,我在循环子数组时遇到问题以获得多个响应。在这种情况下,我想获取当前连接的每个呼叫者ID。

我的SOAP:LITE请求使用以下代码成功从服务器提取数据:

use strict;
use warnings;
use SOAP::Lite;
use CGI;
use Data::Dumper;

my $myWebService = SOAP::Lite
  -> uri('http://www.ShoreTel.com/ProServices/SDK/Web')
  -> proxy('http://10.1.##.##:8070/ShoreTelWebSDK/WebService')
  -> on_action(sub {sprintf '%s/ShoreTelWebService/%s', $_[0], $_[1]});

my $query = new CGI;
my $ip = $query->remote_host;                    # IP address of remote party...use later as unique identifier
my $myClientID = $query->param('MyClientID');    # Possible client ID from previous script passed into us.
my $extnNr = $query->param('MyExtn');            # Has to be at least an extension number so we know who to status.
my $url = CGI::url(-path_info=>1);               # What is my URL?

# There should be an extension number given, else what would we status.

if (defined($refreshNr) &&  defined($extnNr) && ($extnNr ne '') && ($refreshNr ne ''))
{
    # If there is a client ID defined, use it...otherwise registering and getting a client ID
    # is the first thing we need to do when using our web service.

  unless (defined($myClientID))
  {
    # To use our service, we need to register ourselves as a client...use remote IP address
    # as a unique name for association to this session.

    my $regClientResult = $myWebService->RegisterClient(SOAP::Data->name('clientName' => $ip));
    if ($regClientResult->fault)
    {
      print '<p>FAULT', $myClientID->faultcode, ', ', $myClientID->faultstring;
    }
    else
    {
      # Retrieve client ID which we will be using for subsequent communication.

      $myClientID = $regClientResult->valueof('//RegisterClientResponse/RegisterClientResult/');
    }
  }

   if (defined($myClientID))
  {
    # Use our web service to open the line.  This is necessary to get a line ID.

    # print '<br>Client ID ', $myClientID, ' has been registered.<br>';

    my $openResult = $myWebService->OpenLine(SOAP::Data->name('clientHandle' => $myClientID), SOAP::Data->name('lineAddress' => $extnNr));
    my $lineID = $openResult->valueof('//OpenLineResponse/OpenLineResult/lineID/');
    my $lineType = $openResult->valueof('//OpenLineResponse/OpenLineResult/lineType/');
    my $lineName = $openResult->valueof('//OpenLineResponse/OpenLineResult/lineName/');
    my $lineState = $openResult->valueof('//OpenLineResponse/OpenLineResult/lineState/');

# Call GetActiveCalls to see if anything is going on with this line.

    my $result = $myWebService->GetActiveCalls(SOAP::Data->name('clientHandle' => $myClientID), SOAP::Data->name('lineID' => $lineID));

    my $callID = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/callID/');

if ($callID ne '')
    {
      # print '<br>Call ID is ', $callID;

      my $isExternal = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/isExternal/');
      my $isInbound = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/isInbound/');
      my $callReason = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/callReason/');
      my $connectedID = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/connectedID/');
      my $connectedIDName = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/connectedIDName/');
      my $callerID = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/callerID/');
      my $callerIDName = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/callerIDName/');
      my $calledID = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/calledID/');
      my $calledIDName = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/calledIDName/');

      my $callState = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callState/');
      my $callStateDetail = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callStateDetail/');

      # Print call information.

      print <<EndOfCallInfo;
      HTML CODE
EndOfCallInfo

    }
    else
    {
         print <<EndOfCallInfo2;
         HTML CODE

EndOfCallInfo2
    }
  }

}

但我只能访问多维数组中的第一个结果 我已经尝试使用

循环结果
for my $t ($result->result({ShoreTelCallStateInfo}{callInfo}')) {
    print $t->{callerID} . "\n";}

但我绝对没有结果。似乎甚至没有输入循环。

以下代码我的工作正常,但只提取第一个来电显示,在本案例中为1955.

my $callerID = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/callerID/');

我可以做些什么来使我的循环工作?

这样你就可以看到我从服务器收到的内容我已经使用DUMP包含了SOAP服务器的响应:

$VAR1 = { 'ShoreTelCallStateInfo' => [ 
            { 'callStateDetail' => 'Active', 
              'callState' => 'OnHold', 
              'callInfo' => 
                { 'callerIDName' => 'Joel LASTNAME', 
                  'callID' => '69105', 'lineID' => '3947', 
                  'connectedIDName' => 'VM-Forward', 
                  'calledID' => '2105', 
                  'callerID' => '1955', 
                  'isInbound' => 'false', 
                  'calledIDName' => 'VM-Forward', 
                  'callReason' => 'None', 
                  'callUniqueID' => '1369702515', 
                  'connectedID' => '2105', 
                  'isExternal' => 'false', 
                  'callGUID' => '{00030000-66C2-537E-3FD8-0010492377D9}' 
                 } 
            }, 
            { 'callStateDetail' => 'Active', 
              'callState' => 'Connected', 
              'callInfo' => 
                { 'callerIDName' => 'LASTNAME Joel ', 
                  'callID' => '71649', 
                  'lineID' => '3947', 
                  'connectedIDName' => 'LASTNAME Joel ', 
                  'calledID' => '1955', 
                  'callerID' => '+1385#######', 
                  'isInbound' => 'true', 
                  'calledIDName' => 'Joel LASTNAME', 
                  'callReason' => 'None', 
                  'callUniqueID' => '1117287558', 
                  'connectedID' => '+1385#######', 
                  'isExternal' => 'true', 
                  'callGUID' => '{00030000-66C5-537E-3FD8-0010492377D9}' 
                } 
            } 
        ] 
        }; 

1 个答案:

答案 0 :(得分:1)

只是一个猜测......

  

以下代码我工作正常,但只拉第一个调用者   ID,在这种情况下是1955年。

my $callerID = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/callerID/');
     

我可以做些什么来使我的循环工作?

SOAP::Lite docs说:

  

的valueOf()

     

返回(先前)匹配节点的值。它接受一个节点   路径。在这种情况下,它返回匹配节点的值,但不返回   更改当前节点。适合您想要匹配节点和   然后浏览节点子节点:

  $som->match('/Envelope/Body/[1]'); # match method
  $som->valueof('[1]');              # result
  $som->valueof('[2]');              # first out parameter (if present)
     

返回值取决于上下文。 在标量语境中它会   从匹配的节点集返回第一个元素。在数组上下文中   将返回所有匹配的元素。

这会给出您期望的行为吗?它对方法的价值强加了列表上下文。

for my $callerID ($result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/callerID/')) {
      ...
      # do something with each callerID
}

my @callerIDs = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/callerID/');