Archived
1
0
This repository has been archived on 2021-10-08. You can view files and clone it, but cannot push or open issues or pull requests.
ACU/defenses/prepare_xml.pl
2013-06-11 19:29:21 +02:00

159 lines
3.1 KiB
Perl

#! /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