Here's an
XML::Rules solution, though I'm not sure if there may or may not be more than one label per category, or more than one keyword per keywords. I'm assuming "may not", but easy enough to fix if "may" (I would add 'as array no content' rules for label and keyword, and then assume arrays in the parent node's code):
use strict;
use warnings;
use XML::Rules;
my $xml = <<XML;
<?xml version="1.0" encoding="UTF-8"?>
<results>
<url>--removed--</url>
<language>english</language>
<text>---removed---</text>
<taxonomy>
<category>
<label>/vehicle brands/jeep</label>
</category>
<category>
<label>/travel</label>
</category>
</taxonomy>
<keywords>
<keyword>
<text>rear extended bumpstops</text>
</keyword>
</keywords>
</results>
XML
my @rules = (
category => sub {
my $r = $_[1];
print "Category: $r->{label}\n";
},
keywords => sub {
my $r = $_[1];
print "Keywords: $r->{text}\n";
},
keyword => 'pass no content',
_default => 'content',
);
my $xr = XML::Rules->new( rules => \@rules );
$xr->parse($xml);