commit ff1cf9292138b27e5e00bece98a2953bc804ba2f Author: Mercier Pierre-Olivier Date: Tue Jun 11 19:29:21 2013 +0200 Defense script for generating missing IDs diff --git a/defenses/prepare_xml.pl b/defenses/prepare_xml.pl new file mode 100644 index 0000000..a519bd5 --- /dev/null +++ b/defenses/prepare_xml.pl @@ -0,0 +1,158 @@ +#! /usr/bin/env perl + +use v5.10.1; +use strict; +use warnings; +use Getopt::Long; +use Pod::Usage; +use XML::LibXML; + +# Extract IDs and remove duplicates +sub extract_ids (\@@) +{ + my $ids = shift @_; + + foreach my $node (@_) + { + my $att = $node->getAttribute("id"); + if (defined $att) + { + if (grep {$_ eq $att} @$ids) { + $node->removeAttribute("id"); + } + else { + push @$ids, $att; + } + } + } +} + +# Parse arguments +my $input; my $output; +my $help; my $man; +GetOptions ("output|O=s" => \$output, + "help|h|?" => \$help, + "man" => \$man, + "" => \$input) + or pod2usage(2); +pod2usage(1) if $help; +pod2usage(-exitval => 0, -verbose => 2) if $man; + +# Open defense XML file +my $xmlin; +if (defined $input || $#ARGV == -1) { + $xmlin = *STDIN; +} +else { + open $xmlin, "<", $ARGV[0] or die $!; +} + +binmode $xmlin; +my $dom = XML::LibXML->load_xml(IO => $xmlin); +close $xmlin unless $xmlin eq *STDIN; + +# First, get all existing ID and remove duplicates +my @ids; +extract_ids @ids, $dom->getElementsByTagName("group"); +extract_ids @ids, $dom->getElementsByTagName("question"); +extract_ids @ids, $dom->getElementsByTagName("answer"); + +# Then, attribute an ID to node that hasn't +my $grp_i = 0; +foreach my $group ($dom->getElementsByTagName("group")) +{ + my $cur_gid = $group->getAttribute("id"); + if (!defined $cur_gid) { + do { + $cur_gid = "defg".$grp_i; + $grp_i += 1; + } while (grep {$_ eq $cur_gid} @ids); + $group->setAttribute("id", $cur_gid); + } + else { + $grp_i += 1; + } + + my $qst_i = 0; + foreach my $question ($group->getElementsByTagName("question")) + { + my $cur_qid = $question->getAttribute("id"); + if (!defined $cur_qid) { + do { + $cur_qid = $cur_gid."q".$qst_i; + $qst_i += 1; + } while (grep {$_ eq $cur_qid} @ids); + $question->setAttribute("id", $cur_qid); + } + else { + $qst_i += 1; + } + + my $ans_i = 0; + foreach my $answer ($question->getElementsByTagName("answer")) + { + my $cur_aid = $answer->getAttribute("id"); + if (!defined $cur_aid) { + do { + $cur_aid = $cur_qid."a".$ans_i; + $ans_i += 1; + } while (grep {$_ eq $cur_aid} @ids); + $answer->setAttribute("id", $cur_aid); + } + else { + $ans_i += 1; + } + } + } +} + +# Save defense XML file +my $xmlout; +if (defined $output) { + open $xmlout, '>', $output; + binmode $xmlout; +} +else { + $xmlout = *STDOUT; +} +print {$xmlout} $dom->toString(); +close $xmlout unless $xmlout eq *STDOUT; + +__END__ + +=head1 NAME + +prepare_xml.pl - Prepare defense XML by adding id to groups, questions and answers + +=head1 SYNOPSIS + +prepare_xml.pl [options] [file] + +=head1 DESCRIPTION + +Parse the XML file given (or stdin if no file is given) and add id to groups, questions and answers that have any or duplicate id. + + Options: + -output=file.xml save prepared XML to this location + -help brief help message + -man full documentation + +=head1 OPTIONS + +=over 8 + +=item B<-output=file.xml> + +Save the prepared XML to a file instead of printing it on standard output. + +=item B<-help> + +Print a brief help message and exits. + +=item B<-man> + +Prints the manual page and exits. + +=back + +=cut