-4

From morning i was scratching my head to resolve the below requirment. I know how to parse an xml but not able to find out the sollution to get the exact block along with tags.

sample code:

<employee name="sample1">
 <interest name="cricket">
<function action= "bowling">
   <rating> average </rating>
</function>
 </interest>
 <interest name="football">
<function action="defender">
   <rating> good </rating>
</function>
 </interest>
</employee>

I just want to extract the below content from above xml file and write it into another text file.

  <interest name="cricket">
     <function action= "bowling">
        <rating> average </rating>
     </function>
  </interest>

Thanks for your help

Hameed
  • 2,227
  • 1
  • 21
  • 31
user1575765
  • 60
  • 3
  • 10

1 Answers1

2

Using XML::Twig:

#!/usr/bin/perl

use strict;
use warnings;
use XML::Twig;

XML::Twig->new( twig_handlers => { 'interest[@name="cricket"]' => sub { $_->print } },
              )
         ->parsefile( 'interest.xml');

A little explanation: the twig_handler is called when an element satisfying the trigger condition, in this case interest[@name="cricket"], is satisfied. At this point the associated sub is called. In the sub $_ is set to be the current element, which is then print'ed. For more complex subs, 2 arguments are passed, the twig itself (the document) and the current element.

Voilà.

Also with XML::Twig comes a tool called xml_grep, which makes it easy to extract what you want:

xml_grep --nowrap 'interest[@name="cricket"]' interest.xml

the --nowrap option prevents the default behaviour which wraps the results in a containing element.

mirod
  • 15,923
  • 3
  • 45
  • 65
  • Hello Mirod thanlks alot for your help – user1575765 Aug 09 '12 at 08:44
  • Hello Mirod thanlks alot for your help Will it be possilble to get the content under thats means join of element? – user1575765 Aug 09 '12 at 08:44
  • OK, you got me right as I was typing an answer, so here it is anyways: the action attribute would be `$_->first_child( 'function')->att( 'action')` and the rating would be `$_->findvalue( 'function/rating')` or `$_->first_child( 'function')->first_child( 'rating')->text` – mirod Aug 09 '12 at 09:00
  • Mirod, Is there any way to write XML::Twig->new( twig_handlers => { 'interest[@name="cricket"]' => sub { $_->print } }, ) ->parsefile( 'interest.xml'); the output to write into text file instead of printing in console – user1575765 Aug 09 '12 at 11:38
  • as per the docs: use `print_to_file`,. Note that this will work only if you extract 1 single element, otherwise you can open a file and then pass the file handle to print: `open( my $fh, '>', 'my_file.xml') or die "cannot create file: $!";` then in the handler:`$_->print( $fh)` – mirod Aug 09 '12 at 11:54
  • Mirod can you please provide the like to related to document of XML:Twig module. I searched but i didn't found :( – user1575765 Aug 09 '12 at 12:12
  • on Unix: `perldoc XML::Twig` or `man XML::Twig`, also, look at http://xmltwig.org/xmltwig/ – mirod Aug 09 '12 at 12:45