Рассмотрим несколько небольших настроек кода вашего драйвера, приведенных ниже.
#! /usr/bin/env perl
use warnings;
use strict;
use TestResult;
my $tr = TestResult->new;
$tr->parameter(1, 1, "Some Process A Happened");
$tr->parameter(1, 2, "Some Process B Happened");
$tr->parameter(2, 1, "Some Process A Happened");
$tr->parameter(3, 1, "Some Process Happened");
$tr->image(1, "Some info");
$tr->result("Pass");
$tr->comments("Executed Successfully");
print $tr->as_xml;
Вывод XML:
<?xml version="1.0" encoding="UTF-8" ?>
<TestResult xmlns="http://test.com/automate" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://test.com/automate">
<Result>Pass</Result>
<Comments>Executed Successfully</Comments>
<Parameters>
<ParameterGroup ID="Group1">
<Parameter key="Key1">Some Process A Happened</Parameter>
<Parameter key="Key2">Some Process B Happened</Parameter>
</ParameterGroup>
<ParameterGroup ID="Group2">
<Parameter key="Key1">Some Process A Happened</Parameter>
</ParameterGroup>
<ParameterGroup ID="Group3">
<Parameter key="Key1">Some Process Happened</Parameter>
</ParameterGroup>
</Parameters>
<Images>
<Image key="ImageTag1">Some info</Image>
</Images>
</TestResult>
Просмотр содержимого $self->{_xml}
может помочь вашему пониманию.
{
'Comments' => { 'content' => 'Executed Successfully' },
'Parameters' => {
'ParameterGroup' => {
'Group1' => {
'Parameter' => {
'Key2' => { 'content' => 'Some Process B Happened' },
'Key1' => { 'content' => 'Some Process A Happened' }
}
},
'Group3' => {
'Parameter' => {
'Key1' => { 'content' => 'Some Process Happened' }
}
},
'Group2' => {
'Parameter' => {
'Key1' => { 'content' => 'Some Process A Happened' }
}
}
}
},
'xmlns' => 'http://test.com/automate',
'Result' => { 'content' => 'Pass' },
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
'xsi:schemaLocation' => 'http://test.com/automate',
'Images' => {
'ImageTag1' => { 'content' => 'Some info' }
}
}
Модуль TestResult, который доставит вас туда, находится ниже. Обязательно поместите его в файл с именем TestResult.pm
где-нибудь в пути поиска модуля. Все начинается со знакомого шаблона.
package TestResult;
use strict;
use warnings;
use XML::Simple;
Во время компиляции мы настраиваем подкласс XML :: Simple, специфичный для вашего желаемого формата XML, который будет выводить элементы в соответствующем порядке.
BEGIN {
@__PACKAGE__::XML::ISA = qw/ XML::Simple /;
my %order = (
TestResult => [qw/
xmlns xmlns:xsi xsi:schemaLocation
Result Comments Parameters Images
/],
);
*__PACKAGE__::XML::sorted_keys = sub {
my($self,$name,$h) = @_;
return @{ $order{$name} } if $order{$name};
sort keys %$h;
};
}
Каждый экземпляр будет содержать содержимое выходного документа. Жестко закодированные пары ключ-значение становятся атрибутами элемента TestResult.
sub new {
my($class) = @_;
my $self = {
_xml => {
"xmlns" => "http://test.com/automate",
"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
"xsi:schemaLocation" => "http://test.com/automate",
},
};
bless $self => $class;
}
Реализации comments
и result
просты, потому что XML, который они создают, прост. Методы заполняют биты в соответствующих слотах без сюрпризов.
sub comments {
my($self,$comments) = @_;
$self->{_xml}{Comments} = { content => $comments };
}
sub result {
my($self,$result) = @_;
$self->{_xml}{Result} = { content => $result };
}
Мы должны быть осторожны с image
и parameter
, потому что они содержат несколько детей. Слепая перезапись $self->{_xml}{Images}
или $self->{_xml}{Parameter}
приведет к засорению любого контента, который уже был накоплен, поэтому вместо этого мы добавляем новые элементы постепенно.
sub image {
my($self,$image,$desc) = @_;
my $imageid = "ImageTag" . $image;
$self->{_xml}{Images}{$imageid} = { content => $desc };
}
sub parameter {
my($self,$group,$key,$value) = @_;
my $groupid = "Group" . $group;
my $keyid = "Key" . $key;
$self->{_xml}{Parameters}{ParameterGroup}{$groupid}{Parameter}{$keyid} =
{ content => $value };
}
Наконец, мы кодируем XML, используя TestResult :: XML. Параметр GroupTags
объявляет отношения вложенности, , например, , <Images>
содержит <Image>
. (Сначала я попытался дать аналогичную обработку отношениям между <Parameters>
и <ParameterGroup>
и между <ParameterGroup>
и <Parameter>
, но вывод XML отличался от того, что вы хотите.) Параметр KeyAttr
сообщает XML :: Простой в использовании хеш-ключи Perl в качестве атрибутов XML. Префиксы +
дадут более хорошие результаты, если вы когда-либо будете использовать XMLin
для чтения TestResults, сгенерированных другими инструментами.
sub as_xml {
my($self) = @_;
my $serialize = __PACKAGE__::XML->new;
$serialize->XMLout(
$self->{_xml},
GroupTags => {
Images => "Image",
},
KeyAttr => {
ParameterGroup => "+ID",
Parameter => "+key",
Image => "+key",
},
RootName => "TestResult",
XMLDecl => '<?xml version="1.0" encoding="UTF-8" ?>',
);
}
Возвращает истинное значение, указывающее, что модуль успешно загружен.
1;