title: How to loop through subarrays of a SOAP::Lite response in Perl?
body: <p>I have a Perl script that is successfully getting a response from my ShoreTel Phone server.  The server provides information on what calls are currently connected for the extension entered. However I am having issues looping through the sub arrays to get more than one response when there are multiple items. In this case I want to get each of the caller IDs that is currently connected.</p>
  
  <p>My SOAP:LITE request is successfully pulling data from the server using the following code:</p>
  
  <pre><code>use strict;
  use warnings;
  use SOAP::Lite;
  use CGI;
  use Data::Dumper;
  
  my $myWebService = SOAP::Lite
    -&gt; uri('http://www.ShoreTel.com/ProServices/SDK/Web')
    -&gt; proxy('http://10.1.##.##:8070/ShoreTelWebSDK/WebService')
    -&gt; on_action(sub {sprintf '%s/ShoreTelWebService/%s', $_[0], $_[1]});
  
  my $query = new CGI;
  my $ip = $query-&gt;remote_host;                    # IP address of remote party...use later as unique identifier
  my $myClientID = $query-&gt;param('MyClientID');    # Possible client ID from previous script passed into us.
  my $extnNr = $query-&gt;param('MyExtn');            # Has to be at least an extension number so we know who to status.
  my $url = CGI::url(-path_info=&gt;1);               # What is my URL?
  
  # There should be an extension number given, else what would we status.
  
  if (defined($refreshNr) &amp;&amp;  defined($extnNr) &amp;&amp; ($extnNr ne '') &amp;&amp; ($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-&gt;RegisterClient(SOAP::Data-&gt;name('clientName' =&gt; $ip));
      if ($regClientResult-&gt;fault)
      {
        print '&lt;p&gt;FAULT', $myClientID-&gt;faultcode, ', ', $myClientID-&gt;faultstring;
      }
      else
      {
        # Retrieve client ID which we will be using for subsequent communication.
  
        $myClientID = $regClientResult-&gt;valueof('//RegisterClientResponse/RegisterClientResult/');
      }
    }
  
     if (defined($myClientID))
    {
      # Use our web service to open the line.  This is necessary to get a line ID.
  
      # print '&lt;br&gt;Client ID ', $myClientID, ' has been registered.&lt;br&gt;';
  
      my $openResult = $myWebService-&gt;OpenLine(SOAP::Data-&gt;name('clientHandle' =&gt; $myClientID), SOAP::Data-&gt;name('lineAddress' =&gt; $extnNr));
      my $lineID = $openResult-&gt;valueof('//OpenLineResponse/OpenLineResult/lineID/');
      my $lineType = $openResult-&gt;valueof('//OpenLineResponse/OpenLineResult/lineType/');
      my $lineName = $openResult-&gt;valueof('//OpenLineResponse/OpenLineResult/lineName/');
      my $lineState = $openResult-&gt;valueof('//OpenLineResponse/OpenLineResult/lineState/');
  
  # Call GetActiveCalls to see if anything is going on with this line.
  
      my $result = $myWebService-&gt;GetActiveCalls(SOAP::Data-&gt;name('clientHandle' =&gt; $myClientID), SOAP::Data-&gt;name('lineID' =&gt; $lineID));
  
      my $callID = $result-&gt;valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/callID/');
  
  if ($callID ne '')
      {
        # print '&lt;br&gt;Call ID is ', $callID;
  
        my $isExternal = $result-&gt;valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/isExternal/');
        my $isInbound = $result-&gt;valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/isInbound/');
        my $callReason = $result-&gt;valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/callReason/');
        my $connectedID = $result-&gt;valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/connectedID/');
        my $connectedIDName = $result-&gt;valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/connectedIDName/');
        my $callerID = $result-&gt;valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/callerID/');
        my $callerIDName = $result-&gt;valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/callerIDName/');
        my $calledID = $result-&gt;valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/calledID/');
        my $calledIDName = $result-&gt;valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/calledIDName/');
  
        my $callState = $result-&gt;valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callState/');
        my $callStateDetail = $result-&gt;valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callStateDetail/');
  
        # Print call information.
  
        print &lt;&lt;EndOfCallInfo;
        HTML CODE
  EndOfCallInfo
  
      }
      else
      {
           print &lt;&lt;EndOfCallInfo2;
           HTML CODE
  
  EndOfCallInfo2
      }
    }
  
  }
  </code></pre>
  
  <p>But I am only able to access the first result in the multidimensional array.<br>
  I have tried looping through the results using</p>
  
  <pre><code>for my $t ($result-&gt;result({ShoreTelCallStateInfo}{callInfo}')) {
      print $t-&gt;{callerID} . "\n";}
  </code></pre>
  
  <p>But I am getting absolutely no results.  It appears that the the loop is not even entered.</p>
  
  <p>The following code I have works fine, but only pulls the first caller ID, in this case 1955.  </p>
  
  <pre><code>my $callerID = $result-&gt;valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/callerID/');
  </code></pre>
  
  <p>What can I do to make my loop work?</p>
  
  <p>So that you can see what I am receiving from the server I have included the response from the SOAP Server using DUMP :</p>
  
  <pre><code>$VAR1 = { 'ShoreTelCallStateInfo' =&gt; [ 
              { 'callStateDetail' =&gt; 'Active', 
                'callState' =&gt; 'OnHold', 
                'callInfo' =&gt; 
                  { 'callerIDName' =&gt; 'Joel LASTNAME', 
                    'callID' =&gt; '69105', 'lineID' =&gt; '3947', 
                    'connectedIDName' =&gt; 'VM-Forward', 
                    'calledID' =&gt; '2105', 
                    'callerID' =&gt; '1955', 
                    'isInbound' =&gt; 'false', 
                    'calledIDName' =&gt; 'VM-Forward', 
                    'callReason' =&gt; 'None', 
                    'callUniqueID' =&gt; '1369702515', 
                    'connectedID' =&gt; '2105', 
                    'isExternal' =&gt; 'false', 
                    'callGUID' =&gt; '{00030000-66C2-537E-3FD8-0010492377D9}' 
                   } 
              }, 
              { 'callStateDetail' =&gt; 'Active', 
                'callState' =&gt; 'Connected', 
                'callInfo' =&gt; 
                  { 'callerIDName' =&gt; 'LASTNAME Joel ', 
                    'callID' =&gt; '71649', 
                    'lineID' =&gt; '3947', 
                    'connectedIDName' =&gt; 'LASTNAME Joel ', 
                    'calledID' =&gt; '1955', 
                    'callerID' =&gt; '+1385#######', 
                    'isInbound' =&gt; 'true', 
                    'calledIDName' =&gt; 'Joel LASTNAME', 
                    'callReason' =&gt; 'None', 
                    'callUniqueID' =&gt; '1117287558', 
                    'connectedID' =&gt; '+1385#######', 
                    'isExternal' =&gt; 'true', 
                    'callGUID' =&gt; '{00030000-66C5-537E-3FD8-0010492377D9}' 
                  } 
              } 
          ] 
          }; 
  </code></pre>