2011-04-24 90 views
1

我其實問過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', 
); 

的結構,但這些都是固定的結構。我怎樣才能使這種動態適合用戶的需求?

+0

喜池上..請看看我已經試過 – MarsMax 2011-04-24 18:57:37

回答

2

考慮一下你的驅動代碼的一些小調整。

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

commentsresult的實施非常簡單,因爲它們產生的XML很簡單。這些方法在合適的插槽中填充比特並不意外。

sub comments { 
    my($self,$comments) = @_; 
    $self->{_xml}{Comments} = { content => $comments }; 
} 

sub result { 
    my($self,$result) = @_; 
    $self->{_xml}{Result} = { content => $result }; 
} 

我們必須要小心imageparameter,因爲它們含有多個孩子。盲目覆蓋$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; 
+0

謝謝你這麼多Greg..it完美的作品..解釋也很好..再次感謝.. – MarsMax 2011-04-26 05:30:40

+0

嗨格雷格..我一直在努力使參數看起來像發生了一些進程發生了某個過程B發生了一些過程A MarsMax 2011-04-29 06:26:26

+0

通過更改此行來完成此操作getparameter to $ self - > {_ xml} {Parameters} {ParameterGroup} {$ groupid} {Parameter} {$ keyid} = {content => $ value};似乎沒有工作..任何指針? – MarsMax 2011-04-29 06:28:24

1

XML :: Simple期望您將輸出組裝成perl數據結構,然後將其轉換爲XML;你是否在實際調用XML的時候遇到了麻煩,弄清楚數據結構應該是什麼樣子,或者用數據填充它們? (或者完全不同的東西?)

解決你的問題,一次解決它一點。

+0

我已經編輯,其中提到什麼,我已經試過了問題..請看看 – MarsMax 2011-04-24 18:55:22