0

Trying to extract data from detailed -> doc -> params -> parameters -> name in following DoxyDocs1.pm file; also including sample of script that extracts some data, but having trouble extracting params -> parameters -> name. Uncomment commented sections to see data.

#!/bin/perl
use Data::Dumper;
use warnings;
require "DoxyDocs1.pm";
print "API Content Analyzer\n";
&GenerateClassInfo($doxydocs->{classes});
sub GenerateClassInfo()
{
    my ($classes) = @_; 
    foreach my $class (@$classes) {
    print "\nClass name is: $class->{name}\n";
    foreach my $pubmeth (@{$class->{public_methods}->{members}}) {
       print "\n" if exists $pubmeth->{name};
       print "\tpublic methods include: $pubmeth->{name}\n";
       my ($key, $pmcontent) = each (@{$pubmeth->{detailed}->{doc}});
       print "\t\tdescription: $pmcontent->{content}\n" if exists $pmcontent->{content};
       # foreach my $pmp (@{$pubmeth->{detailed}->{doc}}) {
         # print "\t\t";
         # print Dumper($pmp);
       # }
       print "\t\tkind: $pubmeth->{kind}\n";
       print "\t\ttype: $pubmeth->{type}\n" if exists $pubmeth->{type};
    }
    foreach my $privmeth (@{$class->{private_methods}->{members}}) {
        print "\n" if exists $privmeth->{name};
        print "\tprivate methods include: $privmeth->{name}\n";
        my ($key, $pmcontent) = each (@{$privmeth->{detailed}->{doc}});
        print "\t\tdescription: $pmcontent->{content}\n" if exists $pmcontent->{content};
        # foreach my $info (@{$privmeth->{detailed}->{doc}}) {
         # print "\t\t";
         # print Dumper($info);
        # }
        print "\t\tkind: $privmeth->{kind}\n";
        print "\t\ttype: $privmeth->{type}\n" if exists $privmeth->{type};
    }       
  }
}

Example DoxyDocs1.pm file

$doxydocs=
{
  classes => [
    {
     name => 'Panoply::Composite',
     public_methods => {
     members => [
      {
        kind => 'function',
        name => 'addChild',
        virtualness => 'non_virtual',
        protection => 'public',
        static => 'no',
        brief => {},
        detailed => {
          doc => [
            {
              type => 'text',
              content => 'Add a child to the container '
            },
            params => [
              {
                parameters => [
                  {
                    name => 'child'
                  }
                ],
                doc => [
                  {
                    type => 'text',
                    content => 'is the child element to add'
                  }
                ]
              }
            ]
          ]
        },
        type => 'void',
        const => 'no',
        volatile => 'no',
        parameters => [
          {
            declaration_name => 'child',
            type => 'Ptr'
          }
        ]
      },
      {
        kind => 'function',
        name => 'operator<',
        virtualness => 'non_virtual',
        protection => 'public',
        static => 'no',
        brief => {},
        detailed => {
          doc => [
            {
              type => 'text',
              content => 'Less than operator'
            },
            {
              type => 'parbreak'
            },
            params => [
              {
                parameters => [
                  {
                    name => 'rval'
                  }
                ],
                doc => [
                  {
                    type => 'text',
                    content => 'The '
                  },
                  {
                    type => 'url',
                    link => 'classPanoply_1_1Package',
                    content => 'Package'
                  },
                  {
                    type => 'text',
                    content => ' against which we are comparing this one. '
                  }
                ]
              }
            ],
            {
              return => [
                {
                  type => 'text',
                  content => 'true if this.packageID < rval.packageID, false otherwise.'
                }
              ]
            }
          ]
        },
        type => 'bool',
        const => 'yes',
        volatile => 'no',
        parameters => [
          {
            declaration_name => 'rval',
            type => 'const Composite &'
          }
        ]
      },
    ]
  },
  private_methods => {
    members => [
      {
        kind => 'function',
        name => 'addChild',
        virtualness => 'virtual',
        protection => 'private',
        static => 'no',
        brief => {},
        detailed => {
          doc => [
            {
              type => 'text',
              content => 'Add a child to the container '
            },
            params => [
              {
                parameters => [
                  {
                    name => 'child'
                  }
                ],
                doc => [
                  {
                    type => 'text',
                    content => 'is the child element to add '
                  }
                ]
              },
              {
                parameters => [
                  {
                    name => 'parent'
                  }
                ],
                doc => [
                  {
                    type => 'parbreak'
                  },
                  {
                    type => 'text',
                    content => 'is this own parent, except in weak pointer format to avoid a memory leak'
                  }
                ]
              }
            ]
          ]
        },
        type => 'virtual void',
        const => 'no',
        volatile => 'no',
        parameters => [
          {
            declaration_name => 'child',
            type => 'Ptr'
          },
          {
            declaration_name => 'parent',
            type => 'Ptr'
          }
        ]
      },
    ]
  },
    }
  ]
 };
1;
Jeff Cunningham
  • 145
  • 1
  • 11

1 Answers1

1

You said you wanted

detailed -> doc -> params -> parameters -> name 

but that's missing many indexes. Which doc, param and parameters do you want?

detailed -> doc -> ??? -> params -> ??? -> parameters -> ??? -> name

The syntax is:

$member->{detailed}->{doc}->[$i]->{params}->[$j]->{parameters}->[$k]->{name}

Or for short:

$member->{detailed}{doc}[$i]{params}[$j]{parameters}[$k]{name}

If you want to loop over every doc, params, parameter, you can use:

my $docs = $member->{detailed}{doc};
for my $doc (@$docs) {
   my $params = $doc->{params};
   for my $param (@$params) {
      my $parameters = $param->{parameters};
      for my $parameter (@$parameters) {
         ...
      }
   }
}

(Why is doc singular and params and parameters plural??? Why do params have parameters???)

ikegami
  • 367,544
  • 15
  • 269
  • 518
  • Thanks for giving me more insight to this structure, although {params} is not a hash reference and appears to be causing the problem of getting to the parameter name "child". The DoxyDocs file is auto generated from Doxygen and I have no control on its structure, maybe a bug in that application. – Jeff Cunningham Jun 23 '12 at 21:38
  • It's a reference to an array, and I treated it as such. – ikegami Jun 23 '12 at 21:41
  • Oops, what I meant to say is that Data Dumper reports the structure starting with doc that doc is a hash key with a reference to an anonymous array as its value. This array contains 3 elements: a reference to an anonymous hash; the string "params"; and a reference to an anonymous array. I can access the parameter child with this: $pubmeth->{detailed}->{doc}->[2]->[0]->{parameters}->[0]->{name}; There might be a better way that I don't know about. – Jeff Cunningham Jun 25 '12 at 19:31
  • 1
    I see, you're pointing out that I misread `doc => [ { ... }, params => [ ... ] ]`. But that's no surprise, since Data::Dumper will never produce that output! (See `perl -MData::Dumper -e'print Dumper { doc => [ { a=>1,b=>2 }, params => [ "..." ] ] }'`.) How about you start by showing what output you actually got? If you edited your output to try to make it more readable, try adding `local $Data::Dumper::Indent = 1;` instead. – ikegami Jun 25 '12 at 19:58