in reply to Re^2: XML::Twig Help
in thread XML::Twig Help

++mirod, I was unaware of field.

On another topic, you probably didn't see my update regarding access to your excellent website. Were you aware that it has been tough to get to for some time now?

Replies are listed 'Best First'.
Re^4: XML::Twig Help
by onegative (Scribe) on Jan 07, 2011 at 17:08 UTC
    I REALLY appreciate your help team...

    OK, that seems to help me understand handlers better but what about situations where the xml tag has multiple children of the same name? When attempting to use the handler as below I only get the first TYPE element.

    i.e.

    use strict; use XML::Twig; my $xmlstr = <<EOF; <TREES> <APPLE> <TYPE id="1001">Scarlet</TYPE> <TYPE id="1002">Red</TYPE> <TYPE id="1003">Gold</TYPE> <TYPE id="1004">Fuji</TYPE> <TYPE id="1005">Scarlet</TYPE> </APPLE> <PEAR> <TYPE id="1001">Bradford</TYPE> <TYPE id="1002">Cleveland Select</TYPE> <TYPE id="1003">Aristocrat</TYPE> <TYPE id="1004">Autumn Blaze</TYPE> </PEAR> </TREES> EOF my $twig = XML::Twig->new(twig_handlers => {APPLE => \&apple}); $twig->parse($xmlstr); sub apple { my ($t, $elt) = @_; print $elt->att('id'), "\n"; print $elt->field('TYPE' ), "\n"; print "\n"; }
      use warnings; use strict; use XML::Twig; my $xmlstr = <<EOF; <TREES> <APPLE> <TYPE id="1001">Scarlet</TYPE> <TYPE id="1002">Red</TYPE> <TYPE id="1003">Gold</TYPE> <TYPE id="1004">Fuji</TYPE> <TYPE id="1005">Scarlet</TYPE> </APPLE> <PEAR> <TYPE id="1001">Bradford</TYPE> <TYPE id="1002">Cleveland Select</TYPE> <TYPE id="1003">Aristocrat</TYPE> <TYPE id="1004">Autumn Blaze</TYPE> </PEAR> </TREES> EOF my $twig = XML::Twig->new(twig_handlers => {APPLE => \&apple}); $twig->parse($xmlstr); sub apple { my ($t, $elt) = @_; for my $type ($elt->children('TYPE')) { print $type->att('id'), "\n"; print $type->text(), "\n"; print "\n"; } } __END__ 1001 Scarlet 1002 Red 1003 Gold 1004 Fuji 1005 Scarlet

      Use warnings too.

Re^4: XML::Twig Help
by onegative (Scribe) on Jan 10, 2011 at 21:31 UTC
    Good day team,
    I wanted to thank everyone for the suggestions and I seem to be on my way using this module but I am stuck on one final extraction component and not sure exactly what I am doing wrong.

    Below is a sample of the xml and the small snipnet of code I am trying to utilize. But No Joy!

    I would appreciate one final example to help me get over this last hump and I think I will be ok if I could just understand how to walk down the twig just a few elements and then be able to understand the proper way to get further down the twig.

    Again many thanks in advance.

    #!/home/p1aldbw1/aldb/perl-5.12.2/bin/perl use warnings; use strict; use XML::Twig; use Data::Dumper; my $xmlstr = <<EOF; <AGENT hostname="viper3"> <NAMESPACE> <APPCLASS name="ORACLE_AVAILABILITY"> <INSTANCE name="atecr"> <PARAMETER name="InstanceStatus"> <TYPE>CONSUMER</TYPE> <BORDER> <ACTIVE>0</ACTIVE> <MIN>0</MIN> <MAX>0</MAX> <TRIGGER>Immediate</TRIGGER> <RECOVERY>0</RECOVERY> <STATE>OK</STATE> </BORDER> <ALARM1> <ACTIVE>1</ACTIVE> <MIN>1</MIN> <MAX>1</MAX> <TRIGGER>After 7 times</TRIGGER> <RECOVERY>1</RECOVERY> <STATE>WARN</STATE> </ALARM1> <ALARM2> <ACTIVE>1</ACTIVE> <MIN>2</MIN> <MAX>2</MAX> <TRIGGER>After 7 times</TRIGGER> <RECOVERY>1</RECOVERY> <STATE>ALARM</STATE> </ALARM2> </PARAMETER> <PARAMETER name="RSSpaceLeft"> <TYPE>CONSUMER</TYPE> <BORDER> <ACTIVE>0</ACTIVE> <MIN>0</MIN> <MAX>0</MAX> <TRIGGER>Immediate</TRIGGER> <RECOVERY>0</RECOVERY> <STATE>OK</STATE> </BORDER> <ALARM1> <ACTIVE>0</ACTIVE> <MIN>0</MIN> <MAX>0</MAX> <TRIGGER>Immediate</TRIGGER> <RECOVERY>0</RECOVERY> <STATE>OK</STATE> </ALARM1> <ALARM2> <ACTIVE>0</ACTIVE> <MIN>0</MIN> <MAX>0</MAX> <TRIGGER>Immediate</TRIGGER> <RECOVERY>0</RECOVERY> <STATE>OK</STATE> </ALARM2> </PARAMETER> <PARAMETER name="CannotExtend"> <TYPE>CONSUMER</TYPE> <BORDER> <ACTIVE>0</ACTIVE> <MIN>0</MIN> <MAX>0</MAX> <TRIGGER>Immediate</TRIGGER> <RECOVERY>0</RECOVERY> <STATE>OK</STATE> </BORDER> <ALARM1> <ACTIVE>1</ACTIVE> <MIN>1</MIN> <MAX>1</MAX> <TRIGGER>Immediate</TRIGGER> <RECOVERY>1</RECOVERY> <STATE>ALARM</STATE> </ALARM1> <ALARM2> <ACTIVE>0</ACTIVE> <MIN>0</MIN> <MAX>0</MAX> <TRIGGER>Immediate</TRIGGER> <RECOVERY>0</RECOVERY> <STATE>OK</STATE> </ALARM2> </PARAMETER> </INSTANCE> </APPCLASS> <APPCLASS name="ORACLE_CAPACITY"> <INSTANCE name="atecq"> <PARAMETER name="FreeSpace"> <TYPE>CONSUMER</TYPE> <BORDER> <ACTIVE>0</ACTIVE> <MIN>0</MIN> <MAX>0</MAX> <TRIGGER>Immediate</TRIGGER> <RECOVERY>0</RECOVERY> <STATE>OK</STATE> </BORDER> <ALARM1> <ACTIVE>1</ACTIVE> <MIN>1</MIN> <MAX>1</MAX> <TRIGGER>After 7 times</TRIGGER> <RECOVERY>1</RECOVERY> <STATE>WARN</STATE> </ALARM1> <ALARM2> <ACTIVE>1</ACTIVE> <MIN>2</MIN> <MAX>2</MAX> <TRIGGER>After 7 times</TRIGGER> <RECOVERY>1</RECOVERY> <STATE>ALARM</STATE> </ALARM2> </PARAMETER> <PARAMETER name="ExtentsLeft"> <TYPE>CONSUMER</TYPE> <BORDER> <ACTIVE>0</ACTIVE> <MIN>0</MIN> <MAX>0</MAX> <TRIGGER>Immediate</TRIGGER> <RECOVERY>0</RECOVERY> <STATE>OK</STATE> </BORDER> <ALARM1> <ACTIVE>0</ACTIVE> <MIN>0</MIN> <MAX>0</MAX> <TRIGGER>Immediate</TRIGGER> <RECOVERY>0</RECOVERY> <STATE>OK</STATE> </ALARM1> <ALARM2> <ACTIVE>0</ACTIVE> <MIN>0</MIN> <MAX>0</MAX> <TRIGGER>Immediate</TRIGGER> <RECOVERY>0</RECOVERY> <STATE>OK</STATE> </ALARM2> </PARAMETER> <PARAMETER name="CursorsLeft"> <TYPE>CONSUMER</TYPE> <BORDER> <ACTIVE>0</ACTIVE> <MIN>0</MIN> <MAX>0</MAX> <TRIGGER>Immediate</TRIGGER> <RECOVERY>0</RECOVERY> <STATE>OK</STATE> </BORDER> <ALARM1> <ACTIVE>1</ACTIVE> <MIN>1</MIN> <MAX>1</MAX> <TRIGGER>Immediate</TRIGGER> <RECOVERY>1</RECOVERY> <STATE>ALARM</STATE> </ALARM1> <ALARM2> <ACTIVE>0</ACTIVE> <MIN>0</MIN> <MAX>0</MAX> <TRIGGER>Immediate</TRIGGER> <RECOVERY>0</RECOVERY> <STATE>OK</STATE> </ALARM2> </PARAMETER> </INSTANCE> </APPCLASS> </NAMESPACE> </AGENT EOF my $twig = XML::Twig->new(twig_handlers => {NAMESPACE => \&namespace}) +; $twig->parse($xmlstr); my(@NAMESPACE,$APPCLASS,$INSTANCE,$PARAMETER,$PARAM_TYPE); sub namespace { my ($t, $elt) = @_; for my $appclass ( $elt->children() ) { $APPCLASS = $appclass->att('name'); for my $instance ($appclass->children()) { $INSTANCE = $instance->att('name'); for my $parameter ($instance->children()) { $PARAMETER = $parameter->att('name'); $PARAM_TYPE = $parameter->field('TYPE'); @NAMESPACE = $APPCLASS . "~" . $INSTANCE . "~" . $PARA +METER . "~" . $PARAM_TYPE; } } } } print Dumper @NAMESPACE; print "\n\n";


    I must be on the right track because it does in fact return the first branch as expected.

    $VAR1 = 'ORACLE_CAPACITY~atecq~CursorsLeft~CONSUMER';
      Since you didn't specify what your desired output should be, I can only guess. I suspect you want to push into your array. I also simplified the code using join.

      change:

      @NAMESPACE = $APPCLASS . "~" . $INSTANCE . "~" . $PARA +METER . "~" . $PARAM_TYPE;
      to:
      push @NAMESPACE, join '~', $APPCLASS, $INSTANCE, $PARA +METER, $PARAM_TYPE;
      Output:
      $VAR1 = 'ORACLE_AVAILABILITY~atecr~InstanceStatus~CONSUMER'; $VAR2 = 'ORACLE_AVAILABILITY~atecr~RSSpaceLeft~CONSUMER'; $VAR3 = 'ORACLE_AVAILABILITY~atecr~CannotExtend~CONSUMER'; $VAR4 = 'ORACLE_CAPACITY~atecq~FreeSpace~CONSUMER'; $VAR5 = 'ORACLE_CAPACITY~atecq~ExtentsLeft~CONSUMER'; $VAR6 = 'ORACLE_CAPACITY~atecq~CursorsLeft~CONSUMER';
      Side note: Typically, you would pass a reference to Data::Dumper:
      print Dumper(\@NAMESPACE); __END__ $VAR1 = [ 'ORACLE_AVAILABILITY~atecr~InstanceStatus~CONSUMER', 'ORACLE_AVAILABILITY~atecr~RSSpaceLeft~CONSUMER', 'ORACLE_AVAILABILITY~atecr~CannotExtend~CONSUMER', 'ORACLE_CAPACITY~atecq~FreeSpace~CONSUMER', 'ORACLE_CAPACITY~atecq~ExtentsLeft~CONSUMER', 'ORACLE_CAPACITY~atecq~CursorsLeft~CONSUMER' ];

      Side note: use "readmore" tags for large code samples: Writeup Formatting Tips

        DANG!!!!!!!!!!!!!!!

        I'm so stupid...wasn't paying attention...I guess I am in such a hurry that I couldn't see the tree because of the forest.

        Thank you for your help...I have been so focused on the twig code I just didn't catch that...I should know better.