如何动态生成XML?
我其实问过this question in a different form之前。我确实得到了一个很好的答案,但我认为我需要更多的澄清,所以我再次以整个形式提问。如何动态生成XML?
用户将脚本是这样的:
$ABC->Command(100, 100);
my $group = "1";
my $id = "1";
my $value1 = "Some Process A Happened";
$rep->getParameter($group, $id, $value1);
$ABC->Command(100, 100);
my $group = "1";
my $id = "2";
my $value1 = "Some Process B Happened";
$rep->getParameter($group, $id, $value1);
$ABC->Command(100, 100);
my $group = "2";
my $id = "1";
my $value1 = "Some Process A Happened";
$rep->getParameter($group, $id, $value1);
$ABC->Command(100, 100);
my $group = "2";
my $id = "1";
my $value1 = "Some Process Happened";
$rep->getParameter($group, $id, $value1);
$ABC->Command(100, 100);
my $group = "3";
my $id = "1";
my $value1 = "Some Process Happened";
$rep->getParameter($group, $id, $value1);
$ABC->SomeImage($image) $desc = "Some info";
$rep->getImage($image, $desc);
$rep->getResult("Pass")
这必须生成一个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 Value</Parameter>
<Parameter key="Key2">Some Value</Parameter>
<Parameter key="Key3">Some Value</Parameter>
</ParameterGroup>
<ParameterGroup ID="Group2">
<Parameter key="Key1">Some Value</Parameter>
<Parameter key="Key2">Some Value</Parameter>
<Parameter key="Key3">Some Value</Parameter>
</ParameterGroup>
<ParameterGroup ID="Group3">
<Parameter key="Key1">Some Value</Parameter>
<Parameter key="Key2">Some Value</Parameter>
<Parameter key="Key3">Some Value</Parameter>
</ParameterGroup>
</Parameters>
<Images>
<Image key="ImageTag1">info</Image>
<Image key="ImageTag2">info</Image>
<Image key="ImageTag3">info</Image>
</Images>
</TestResult>
图像值和参数值将在不同的时间点的输入。但是他们必须收集并放置在Images
元素内,类似地Parameters
。我应该在这里遵循什么方法?请提供一些代码示例。
编辑:
我有类似
$xml = {
ParameterGroup => [
{
ID => 'Group1',
Parameter => {
Key1 => {content => 'Some Value'},
Key2 => {content => 'Some Value'},
Key3 => {content => 'Some Value'},
},
},
{
ID => 'Group2',
Parameter => {
Key1 => {content => 'Some Value'},
Key2 => {content => 'Some Value'},
Key3 => {content => 'Some Value'},
},
},
]
};
print XMLout(
$xml,
RootName => 'Parameters',
KeyAttr => 'value',
);
的结构,但这些都是固定的结构。我怎样才能使这种动态适合用户的需求?
考虑一下你的驱动代码的一些小调整。
#! /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 ::简单具体的子类到你想要的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 };
}
最后,我们使用TestResult :: XML对XML进行编码。 GroupTags
参数声明嵌套关系,例如,<Images>
包含<Image>
。 (起初,我试图对<Parameters>
和<ParameterGroup>
之间的关系以及<ParameterGroup>
和<Parameter>
之间的关系给予类似的处理,但XML输出与您想要的不同。)KeyAttr
参数告诉XML :: Simple将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;
谢谢你这么多Greg..it完美的作品..解释也很好..再次感谢.. – MarsMax 2011-04-26 05:30:40
嗨格雷格..我一直在努力使参数看起来像
通过更改此行来完成此操作getparameter to $ self - > {_ xml} {Parameters} {ParameterGroup} {$ groupid} {Parameter} {$ keyid} = {content => $ value};似乎没有工作..任何指针? – MarsMax 2011-04-29 06:28:24
XML :: Simple期望您将输出组装成perl数据结构,然后将其转换为XML;你是否在实际调用XML的时候遇到了麻烦,弄清楚数据结构应该是什么样子,或者用数据填充它们? (或者完全不同的东西?)
解决你的问题,一次解决它一点。
我已经编辑,其中提到什么,我已经试过了问题..请看看 – MarsMax 2011-04-24 18:55:22
喜池上..请看看我已经试过 – MarsMax 2011-04-24 18:57:37