carcassonne has asked for the wisdom of the Perl Monks concerning the following question:

All,

I'm trying to simply retrieve some info from a OpenOffice Draw document section using XML::Twig. I have tried several variations but can't get to the data inside the section.

I'd like to be able to read the 'draw:name' in the following:

<draw:frame draw:id="id2" draw:layer="layout" draw:name="objectName" d +raw:style-name="gr1" draw:text-style-name="P3" [svg skipped] <draw:text-box> <text:p text:style-name="P1"> <text:span text:style-name="T2">objectData</text:span> </text:p> </draw:text-box> </draw:frame>

I can get the 'objectData' text of that draw:frame section. How can the draw:name attribute be read ? Here's what I do to get the text:

my $twig = XML::Twig->new ( parse_param_ent => 1, twig_handlers => { 'draw:frame' => \&getDrawInfo, }, ); $twig->parsefile("file.xml"); sub getDrawInfo { my ($t, $data)= @_; print "DEBUG " . $data->text . "\n"; }

I've tried accessing subsections of draw:frame in many ways although none of them returned the draw:name attribute

Thanks for any suggestions/insight.

Replies are listed 'Best First'.
Re: XML::Twig and oodraw
by toolic (Bishop) on Oct 09, 2009 at 15:18 UTC
    If you are just trying to print the value of the 'draw:name' attribute, the use the att method. I had to fix the 1st line of your XML to make it valid.
    use strict; use warnings; use XML::Twig; my $xmlStr = <<XML; <draw:frame draw:id="id2" draw:layer="layout" draw:name="objectName" d +raw:style-name="gr1" draw:text-style-name="P3"> <draw:text-box> <text:p text:style-name="P1"> <text:span text:style-name="T2">objectData</text:span> </text:p> </draw:text-box> </draw:frame> XML my $twig= new XML::Twig( twig_handlers => { 'draw:frame' => \&getDrawInfo } ); $twig->parse($xmlStr); exit; sub getDrawInfo { my ($t, $data) = @_; print $data->att('draw:name'), "\n"; } __END__ objectName
      Thanks. The $data->att('draw:name') you are using requires less typing and makes it more to the point.
Re: XML::Twig and oodraw
by mickep76 (Beadle) on Oct 09, 2009 at 15:08 UTC

    This might work.

    #!/usr/bin/perl use strict; use XML::Twig; my $xml = <<__XML__; <draw:frame draw:id="id2" draw:layer="layout" draw:name="objectName" d +raw:style-name="gr1" draw:text-style-name="P3"> <draw:text-box> <text:p text:style-name="P1"> <text:span text:style-name="T2">objectData</text:span> </text:p> </draw:text-box> </draw:frame> __XML__ my $twig = XML::Twig->new( twig_handlers => { 'draw:frame' => \&handler }, pretty_print => 'indented' ); $twig->parse($xml); sub handler { my ($twig, $elt) = @_; printf "%s\n", $elt->{'att'}->{'draw:name'}; }
      Thanks. I was just about to update my query with the following: ;-)

      sub getDrawInfo { my ($t, $data)= @_; my $name = $data->{'att'}->{'draw:name'}; print "DEBUG name: $name\n"; print "DEBUG " . $data->text . "\n"; }

      Works fine.

        It is cleaner to use the proper method instead of relying on the implementation of the object: $data->att( 'draw:name').

        This way if I ever decide to change the implementation, your code won't break. Not that it is likely at this point, but hey, you never know, there is no promise in the documentation that the attributes be stored in the att field.