Loading ...
Sorry, an error occurred while loading the content.

Slow XPATH loops for parsing array of hashes

Expand Messages
  • Paul Harman
    I m writing a SOAP::Lite client trying to process the following response signature . Hopefully the names/types show what is going on:
    Message 1 of 1 , Mar 3, 2004
    View Source
    • 0 Attachment
      I'm writing a SOAP::Lite client trying to process the following response
      "signature". Hopefully the names/types show what is going on:

      <SOAP-ENV:Body>
      <gv:getMultiNodeFieldsFromIDsResponse>
      <nodeInfo xsi:type="gv:VectorMapStringString">
      <item xsi:type="gv:MapStringString">
      <item xsi:type="gv:StringPair">
      <name></name>
      <value></value>
      </item>
      </item>
      </nodeInfo>
      </gv:getMultiNodeFieldsFromIDsResponse>
      </SOAP-ENV:Body>

      Essentially what this is trying to model on perh terms is an array of
      hashes: the "StringPair item" is a single hash entry, the "MapStringString
      item" is a single hash, ans the "VectorMapStringString nodeInfo" represents
      the array.

      Having successfully used the xpath-based parser before, I thught I'd try it
      again:

      my %storyFields;
      my $i=0;
      foreach my $a ($res->dataof("//nodeInfo/*"))
      {
      my ($name, $value);
      $i++;
      my $j=0;
      my %fields;
      foreach my $b ($res->dataof("//nodeInfo/[$i]/*"))
      {
      $j++;
      foreach my $c ($res->dataof("//nodeInfo/[$i]/[$j]/*"))
      {
      $name=$c->value if($c->name eq "name");
      $value=$c->value if($c->name eq "value");
      }
      $fields{$name}=$value if(defined($name) && defined($value));
      }
      my $id=$fields{id};
      foreach my $f (keys %fields)
      {
      print "->\t\t$id: $f\n";
      next if($f eq "id");
      $storyFields{$id}{$f}=$fields{$f};
      }
      }

      ...which works, but is *chronically* slow. Sticking "print" statements in
      the above, I watch it taking about 2 seconds per item in the array... The
      array contains approx 300 items, each hash contains 6 entries, one of which
      can be a name-value pair where the value is 2k of text. Net result: one
      rather large XML file that takes eons to parse.

      I was wondering what optimisations on the above I can bring to bare. Using
      trace() seems to show that $res->result is available very quickly, it's
      simply going round these XPATH loops that's painfully slow.

      Is there anything useful I can do with the $a and $b references that means I
      can avoid the inner loops' XPATH expressions: i.e. can I not do something
      like:

      foreach my $a ($res->dataof("//nodeInfo/*"))
      foreach my $b ($a->children)
      foreach my $c ($b->children)
      # add to my own hash here

      Thanks for your help,

      Paul


      This E-Mail and any attachment is intended only for the person or entity for
      which it is addressed and may contain confidential material. If you are not
      the addressee or have received this E-Mail in error, please inform the
      sender immediately and delete it from your computer. In addition, if you are
      not the addressee or have received this E-Mail in error, any disclosure,
      copying, distribution or any action taken or omitted to be taken in reliance
      upon it is prohibited and may be unlawful.
      If this E-Mail has been transmitted outside the ordinary course of its
      business, the company for which the sender works accepts no liability for
      any loss or damage suffered by any person arising from any use of or
      reliance on information contained in this E-Mail, and any opinion expressed
      in this E-Mail is personal to the sender and may not reflect the opinion of
      such company. Although the network operator makes every reasonable effort to
      keep its network free from viruses, neither the network operator nor the
      sender or the company for which the sender works accepts any responsibility
      for computer viruses transmitted through this E-Mail or any attachments; it
      is your responsibility to virus scan this E-Mail and any attachments. Any
      E-Mail reply to this address may be subject to interception or monitoring
      for operational reasons or for lawful business practices.
    Your message has been successfully submitted and would be delivered to recipients shortly.