Import old talks from 2010 and 2011 (Boston).
[libguestfs-talks.git] / 2011-boston / talk / xpath
1 #!/usr/bin/perl -w
2
3 eval 'exec /usr/bin/perl -w -S $0 ${1+"$@"}'
4     if 0; # not running under some shell
5 use strict;
6
7 $| = 1;
8
9 unless (@ARGV >= 1) {
10         print STDERR qq(Usage:
11 $0 [filename] query
12                                 
13         If no filename is given, supply XML on STDIN.
14 );
15         exit;
16 }
17
18 use XML::XPath;
19
20 my $xpath;
21
22 my $pipeline;
23
24 if ($ARGV[0] eq '-p') {
25         # pipeline mode
26         $pipeline = 1;
27         shift @ARGV;
28 }
29 if (@ARGV >= 2) {
30         $xpath = XML::XPath->new(filename => shift(@ARGV));
31 }
32 else {
33         $xpath = XML::XPath->new(ioref => \*STDIN);
34 }
35
36 my $nodes = $xpath->find(shift @ARGV);
37
38 unless ($nodes->isa('XML::XPath::NodeSet')) {
39 NOTNODES:
40         print $nodes->value, "\n";
41         exit;
42 }
43
44 if ($pipeline) {
45         $nodes = find_more($nodes);
46         goto NOTNODES unless $nodes->isa('XML::XPath::NodeSet');
47 }
48
49 if ($nodes->size) {
50         foreach my $node ($nodes->get_nodelist) {
51                 print $node->toString;
52         }
53 }
54 else {
55         print STDERR "No nodes found";
56 }
57
58 print "\n";
59
60 exit;
61
62 sub find_more {
63         my ($nodes) = @_;
64         if (!@ARGV) {
65                 return $nodes;
66         }
67         
68         my $newnodes = XML::XPath::NodeSet->new;
69         
70         my $find = shift @ARGV;
71         
72         foreach my $node ($nodes->get_nodelist) {
73                 my $new = $xpath->find($find, $node);
74                 if ($new->isa('XML::XPath::NodeSet')) {
75                         $newnodes->append($new);
76                 }
77                 else {
78                         warn "Not a nodeset: ", $new->value, "\n";
79                 }
80         }
81         
82         return find_more($newnodes);
83 }