我是xml的新手。我有10个XML文件,其中包含一些“挤压报告”,如下所示(我不是在寻找答案,只是指导我如何处理它):
<SquishReport>
<test name="mat_tst_versions">
<prolog time="2015-06-16T13:49:54+02:00"/>
<message type="FATAL" time="2015-06-16T13:50:54+02:00">
<description><![CDATA[Execution error]]></description>
<description type="DETAILED"><![CDATA[squishrunner exited with code 3 when executing tst_start_app]]></description>
</message>
<test name="tst_check_versions">
<prolog time="2015-06-16T13:50:55+02:00"/>
<message line="274" type="LOG" file="C:\test\scripts\utilities.py" time="2015-06-16T13:50:59+02:00">
<description><![CDATA[is 64 bit windows version: True]]></description>
</message>
<message line="124" type="LOG" file="C:\test\mat_tst\tst_check_versions\test.py" time="2015-06-16T13:50:59+02:00">
<description><![CDATA[ path exists!]]></description>
</message>
<message line="129" type="FAIL" file="C:\test\mat_tst\tst_check_versions\test.py" time="2015-06-16T13:50:59+02:00">
<description><![CDATA[expected version: 1.0.0.107]]></description>
</message>
<verification line="132" type="" name="" file="C:\test\mat_tst\tst_check_versions\test.py">
<result type="PASS" time="2015-06-16T13:50:59+02:00">
<description>version check test case passes!</description>
<description type="DETAILED"></description>
</result>
</verification>
<epilog time="2015-06-16T13:50:59+02:00"/>
</test>
<test name="tst_scheduler_1">
<prolog time="2015-06-16T13:51:00+02:00"/>
<message line="62" type="LOG" file="C:\test\mat_tst\tst_scheduler_1\test.py" time="2015-06-16T13:51:00+02:00">
<description><![CDATA[count = 0]]></description>
</message>
<message line="125" type="LOG" file="C:\test\scripts\start_stop.py" time="2015-06-16T13:51:06+02:00">
<description><![CDATA[duration of start of C: 5132ms]]></description>
</message>
<message line="172" type="LOG" file="C:\test\mat_tst\tst_scheduler_1\test.py" time="2015-06-16T13:51:19+02:00">
<description><![CDATA[application name = C]]></description>
</message>
<message line="184" type="LOG" file="C:\test\mat_tst\tst_scheduler_1\test.py" time="2015-06-16T13:51:19+02:00">
<description><![CDATA[start application: C]]></description>
</message>
<message line="213" type="LOG" file="C:\test\mat_tst\tst_scheduler_1\test.py" time="2015-06-16T13:51:19+02:00">
<description><![CDATA[Scheduler Label exists]]></description>
</message>
<message line="219" type="LOG" file="C:\test\mat_tst\tst_scheduler_1\test.py" time="2015-06-16T13:51:19+02:00">
<description><![CDATA[Scheduler Counter exists]]></description>
</message>
<verification line="368" type="" name="" file="C:\test\mat_tst\tst_scheduler_1\test.py">
<result type="FAIL" time="2015-06-16T13:52:01+02:00">
<description>different types elements</description>
<description type="DETAILED"></description>
</result>
</verification>
<verification line="369" type="" name="" file="C:\test\mat_tst\tst_scheduler_1\test.py">
<result type="FAIL" time="2015-06-16T13:52:01+02:00">
<description>name_list= ['Scheduler', 'NCU', 'PLCSimAdv', 'simNCK', 'MCP']</description>
<description type="DETAILED"></description>
</result>
</verification>
<verification line="370" type="" name="" file="C:\test\mat_tst\tst_scheduler_1\test.py">
<result type="FAIL" time="2015-06-16T13:52:01+02:00">
<description>typ_list= ['Scheduler', u'NCU', u'PLCSimAdv']</description>
<description type="DETAILED"></description>
</result>
</verification>
<message line="393" type="LOG" file="C:\test\mat_tst\tst_scheduler_1\test.py" time="2015-06-16T13:52:08+02:00">
<description><![CDATA[:840evoVC.lblClockCounter_Edit = 0]]></description>
</message>
<verification line="411" type="" name="" file="C:\test\mat_tst\tst_scheduler_1\test.py">
<result type="FAIL" time="2015-06-16T13:52:08+02:00">
<description>scheduler counter 1. read, n=0: Scheduler= 0</description>
<description type="DETAILED"></description>
</result>
</verification>
<verification line="414" type="" name="" file="C:\test\mat_tst\tst_scheduler_1\test.py">
<result type="FAIL" time="2015-06-16T13:52:08+02:00">
<description>scheduler counter 2. read, n=0: Scheduler= 0</description>
<description type="DETAILED"></description>
</result>
</verification>
<message line="421" type="LOG" file="C:\test\mat_tst\tst_scheduler_1\test.py" time="2015-06-16T13:52:08+02:00">
<description><![CDATA[scheduler counter 1. read < counter 2. read, n=0: Scheduler= 0]]></description>
</message>
<message line="484" type="ERROR" file="C:\test\mat_tst\tst_scheduler_1\test.py" time="2015-06-16T13:52:29+02:00">
<description><![CDATA[Script Error]]></description>
<description type="DETAILED"><![CDATA[LookupError: Object ':840evoVC.chkSchedule_CheckBox_2' not ready.]]></description>
</message>
<epilog time="2015-06-16T13:52:29+02:00"/>
</test>
<test name="tst_run_plc">
<prolog time="2015-06-16T13:52:30+02:00"/>
<verification line="45" type="" name="" file="C:\test\mat_tst\tst_run_plc\test.py">
<result type="FAIL" time="2015-06-16T13:52:30+02:00">
<description>user path folder already exists!</description>
<description type="DETAILED"></description>
</result>
</verification>
<message line="125" type="LOG" file="C:\test\scripts\start_stop.py" time="2015-06-16T13:52:34+02:00">
<description><![CDATA[duration of start of 840evoVC: 4263ms]]></description>
</message>
<message line="54" type="LOG" file="C:\test\mat_tst_840evovc\tst_run_plc\test.py" time="2015-06-16T13:52:34+02:00">
<description><![CDATA[start ok, duration = 4263000]]></description>
</message>
<message line="64" type="LOG" file="C:\test\mat_tst_840evovc\tst_run_plc\test.py" time="2015-06-16T13:52:34+02:00">
<description><![CDATA[application started: 840evoVC]]></description>
</message>
<message line="78" type="LOG" file="C:\test\mat_tst_840evovc\tst_run_plc\test.py" time="2015-06-16T13:52:39+02:00">
<description><![CDATA[PLC Sim Advanced tmp user files are the expected files]]></description>
</message>
<message line="263" type="LOG" file="C:\test\scripts\start_stop.py" time="2015-06-16T13:52:45+02:00">
<description><![CDATA[all applications are closed]]></description>
</message>
<message line="87" type="LOG" file="C:\test\mat_tst_840evovc\tst_run_plc\test.py" time="2015-06-16T13:52:45+02:00">
<description><![CDATA[close application ok]]></description>
</message>
<epilog time="2015-06-16T13:52:45+02:00"/>
</test>
<test name="tst_app_resources">
<prolog time="2015-06-16T13:52:47+02:00"/>
<message line="65" type="LOG" file="C:\test\mat_tst\tst_app_resources\test.py" time="2015-06-16T13:52:49+02:00">
<description><![CDATA[count:0]]></description>
</message>
<message line="125" type="LOG" file="C:\test\scripts\start_stop.py" time="2015-06-16T13:52:53+02:00">
<description><![CDATA[duration of start: 4176ms]]></description>
</message>
<message line="73" type="LOG" file="C:\test\mat_tst\tst_app_resources\test.py" time="2015-06-16T13:52:53+02:00">
<description><![CDATA[start ok, duration = 4176000]]></description>
</message>
<message line="43" type="LOG" file="C:\test\scripts\win32utilities.py" time="2015-06-16T13:53:00+02:00">
<description><![CDATA[Application 840evovc only exists once]]></description>
</message>
<message line="138" type="ERROR" file="C:\test\mat_tst_\tst_app_resources\test.py" time="2015-06-16T13:53:30+02:00">
<description><![CDATA[Script Error]]></description>
<description type="DETAILED"><![CDATA[LookupError: Object ':chkSchedule_CheckBox_2' not ready.
Called from:
C:\test\mat_tst\tst_app_resources\test.py: 82]]></description>
</message>
<epilog time="2015-06-16T13:53:30+02:00"/>
</test>
<test name="tst_reset">
<prolog time="2015-06-16T13:53:32+02:00"/>
<message line="260" type="LOG" file="C:\test\scripts\start_stop.py" time="2015-06-16T13:56:12+02:00">
<description><![CDATA[Process exited.]]></description>
</message>
<message line="263" type="LOG" file="C:\test\scripts\start_stop.py" time="2015-06-16T13:56:12+02:00">
<description><![CDATA[all applications are closed]]></description>
</message>
<message line="284" type="LOG" file="C:\test\mat_tst\tst_reset\test.py" time="2015-06-16T13:56:12+02:00">
<description><![CDATA[application closed]]></description>
</message>
<verification line="287" type="" name="" file="C:\test\mat_tst\tst_reset\test.py">
<result type="PASS" time="2015-06-16T13:56:12+02:00">
<description>tst_reset_1 ok</description>
<description type="DETAILED"></description>
</result>
</verification>
<epilog time="2015-06-16T13:56:12+02:00"/>
</test>
<epilog time="2015-06-16T13:56:13+02:00"/>
</test>
</SquishReport>
现在我想创建另一个XML文件,其中包含XML文件的摘要。我需要在新的XML文件中只需要每个文件的</test>
</SquishReport>
然后一行链接
<result state= "Passed" href="link to the file"*.xml />
如果"Passed"
<result type="PASS"
,则 "NOT Passed"
。
总的来说,我对新XML文件的期望是:
<?xml version="1.0" encoding="utf-8"?>
<summary>
<testcase name="name of testcase1">
<result state= "Passed" href="link to file1"*.xml /> (for the first file)
<result state= "Passed" href="link to file2"*.xml /> (for the second file)
......
<testcase/>
<testcase name="name of testcase2">
<result state= "Passed" href="link to file1"*.xml /> (for the first file)
<result state= "Passed" href="link to file2"*.xml /> (for the second file)
......
<testcase/>
....
<testcase name="name of testcasen">
<result state= "Passed" href="link to file1"*.xml /> (for the first file)
<result state= "Passed" href="link to file2"*.xml /> (for the second file)
......
<testcase/>
<summary/>
编辑:这是我到目前为止所拥有的:
sub FileCount
{
chdir( $dir ) or die "Couldn't go inside $dir directory, $!";
opendir(my $dh, $dir) or die "$0: $dir: $!\n";
while (my $file = readdir($dh)) {
# We only want files
next unless (-f "$dir/$file");
# Use a regular expression to find files ending in .xml
next unless ($file =~ m/$suff$/);
my $xml = XML::LibXML->load_xml(location => $file);
# Iterate the entries
for my $test ($xml->findnodes('/SquishReport/test/test')) {
my $name_test = $test->findvalue('@name');
# looks for if the results is OK or not
for my $result ($test->findnodes('./verification/result')) {
my $type_result = $result->findvalue('@type');
### -----------------------------------------------------------------------
my $doc = XML::LibXML::Document->new('1.0', 'utf-8');
my $root = $doc->createElement("summary");
$root->setAttribute('testcase_name'=> "$name_test");
for my $case_name (keys %tags) {
my $tag = $doc->createElement($case_name);
my $value = $tags{$case_name};
$tag->appendTextNode($value);
$root->appendChild($tag);
}
$doc->setDocumentElement($root);
### -----------------------------------------------------------------------
print "$type_result = $value_result \n";
if (($type_result eq "WARNING") || ($type_result eq "FAIL") || ($type_result eq "ERROR") || ($type_result eq "FATAL")){
$value_result = "OK";
print "*********** $name_test is not OK *********** \n\n ";
}
else{
$value_result = "NOT_OK";
print "*********** $name_test is OK *********** \n\n ";
}
}
print "\n";
}
#}
print "$file\n";
$count = $count + 1;
}
closedir($dh);
my $filename = 'report.xml';
open(my $fh, '>', $filename) or die "Could not open file '$filename' $!";
print $fh $doc->toString();
close $fh;
答案 0 :(得分:2)
我会这样做:
XML::Twig
(因为我喜欢它)。cut
中的paste
和XML::Twig
方法传输内容(并在必要时修剪)。我非常确定XML::LibXML
也可以这样做,如果您愿意的话。有点像这样:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
my $new_xml = XML::Twig->new( pretty_print => 'indented_a' );
$new_xml->set_root( XML::Twig::Elt->new('summary') );
$new_xml->set_xml_version('1.0');
$new_xml->set_encoding('utf-8');
my $input_processor = XML::Twig->new->parsefile('sample_squish.xml');
foreach my $result ( $input_processor->findnodes('//result') ) {
$result->cut;
$result->paste( $new_xml->root );
}
open( my $output, '>', 'summary.xml' ) or die $!;
print {$output} $new_xml->sprint;
close($output);
您需要:
foreach
/ glob
findnodes
表达式。以上只收集result
个元素,但我认为你想要更多。请记住 - 您可以再次findnodes
,或使用children
作用于...子节点,或parent
作用于父节点。 (例如$result -> parent -> att('file')
)我无法弄清楚您的测试用例/名称如何从源映射到摘要 - 因此,如果您愿意,知道可以添加 new 节点也可能有用:< / p>
my $testcase = $new_xml -> root -> insert_new_elt('testcase', { name => "name_of_the_test" });
$testcase ->set_att('some_other_att', 42);
$result->cut;
$result->paste( $testcase );
这会将$result
元素从一个文件插入到新文档中新创建的testcase
元素中。
答案 1 :(得分:0)
您正在为每个测试创建一个文件。您需要将文档创建(以及根创建等)提升出循环。
XPATH / SquishReport / test / test看起来好像应该是/ SquishReport / test
而且,在某些时候你需要用$ doc做一些事情(比如写一个文件)