G'day Ppeoc,
I started to write an XML::LibXML solution but got distracted (with real world stuff). In the meantime, you've updated your post and have possibly settled on an XML::Twig solution.
[Aside: Please don't update your posts without indicating what's changed - see "How do I change/delete my post?" for more details on this.]
Anyway, the code's written, and seems to do the type of thing you're after, so here it is.
It is intended to be a guide only — you'll need to adapt it for your specific needs.
You gave no indication of the XML you're working with.
I've dummied up 'pm_1148640_xml_parse.xml' for demonstration purposes:
<library>
<category>
<name>Fiction</name>
<book>
<title>Sci-Fi</title>
<title>Detective</title>
</book>
</category>
<category>
<name>History</name>
<book>
<title>Modern</title>
<title>Ancient</title>
</book>
</category>
</library>
Here's the code (pm_1148640_xml_parse.pl):
#!/usr/bin/env perl
use strict;
use warnings;
use XML::LibXML;
my $parser = XML::LibXML::->new();
my $doc = $parser->load_xml(location => 'pm_1148640_xml_parse.xml');
get_category($doc);
sub get_category {
my ($doc) = @_;
my @categories = $doc->findnodes('/library/category/name/text()');
push @categories, 'Exit';
my $selection = 0;
print "Select a book category:\n";
print ++$selection, ". $_\n" for @categories;
my $choice = get_user_selection({ map { $_ => undef } 1 .. $select
+ion});
return if $choice == $selection;
get_book($doc, $categories[$choice - 1]);
}
sub get_book {
my ($doc, $category) = @_;
my $xpath = "/library/category[name=\"$category\"]/book/title/text
+()";
my @books = $doc->findnodes($xpath);
push @books, 'Back to Categories';
my $selection = 0;
print "Select a $category book:\n";
print ++$selection, ". $_\n" for @books;
my $choice = get_user_selection({ map { $_ => undef } 1 .. $select
+ion});
if ($choice == $selection) {
get_category($doc);
return;
}
print "You selected the $category book: '$books[$choice - 1]'\n";
}
sub get_user_selection {
my $valid_selection = shift;
my $selection = '';
while (1) {
print 'Enter selection: ';
chomp($selection = scalar <>);
last if exists $valid_selection->{$selection};
print "Invalid selection [$selection]\n";
}
return $selection;
}
And here's an example run:
$ pm_1148640_xml_parse.pl
Select a book category:
1. Fiction
2. History
3. Exit
Enter selection: 9
Invalid selection [9]
Enter selection: 1
Select a Fiction book:
1. Sci-Fi
2. Detective
3. Back to Categories
Enter selection: 3
Select a book category:
1. Fiction
2. History
3. Exit
Enter selection: 2
Select a History book:
1. Modern
2. Ancient
3. Back to Categories
Enter selection: 2
You selected the History book: 'Ancient'
|