我正在使用Extracting data from an XML document that uses namespaces的第一个答案来使用Perl创建XML文件。
这是我的代码:
use strict;
use warnings;
use feature qw( say );
use XML::LibXML;
use XML::Simple;
use XML::LibXML::XPathContext qw( );
use XML::Writer;
use IO::File;
use File::Copy;
use List::Util;
###****************************************************************
my $dir = "D:/XML";
my $count = 0;
my $entry;
my $case;
my $xmlFile;
my $case_entry;
my $entry_name;
my $result;
my $value_result;
my $value_result_end;
my $type_result;
my @testFile = <*.xml>;
my $arrSize = @testFile;
my @testCase;
my $testCasesize = @testCase;
my @test_result;
my $test_resultsize = @test_result;
#################################################################################
sub WriteXML {
chdir( $dir ) or die "Couldn't go inside $dir directory, $!";
opendir( my $dh, $dir ) or die "$0: $dir: $!\n";
###****************************************************************
my $output = IO::File->new( ">test.xml" );
my $writer = XML::Writer->new( OUTPUT => $output );
$writer->xmlDecl( 'utf-8' );
$writer->pi( 'xml-stylesheet', 'type="text/xsl" href="file:///D:/XML/xml2html_new.xslt"' );
$writer->startTag( "Summary" );
$writer->characters( "\n" );
$writer->startTag( "test", "name" => "Test_tst" );
$writer->characters( "\n" );
###****************************************************************
my $xpc = XML::LibXML::XPathContext->new();
$xpc->registerNs( sr => 'http://www.froglogic.com/XML2' );
my $doc = XML::LibXML->load_xml( location => $testFile[0] );
for $entry ( $xpc->findnodes( '/sr:SquishReport/sr:test/sr:test', $doc ) ) {
$testCase[$count] = $entry->getAttribute( 'name' );
$count = $count + 1;
}
for $case ( @testCase ) {
$writer->startTag( "test", "name" => "$case" );
$writer->characters( "\n" );
for $xmlFile ( @testFile ) {
my $docFile = XML::LibXML->load_xml( location => $xmlFile );
my $attribute = qq(\@name="$case");
my $num = 0;
for $case_entry ( $xpc->findnodes( "//sr:SquishReport/sr:test/sr:test[$attribute]/sr:verification/sr:result", $docFile ) ) {
$type_result = $case_entry->findvalue( '@type' );
if ( ( $type_result eq "FAIL" ) || ( $type_result eq "ERROR" ) || ( $type_result eq "FATAL" ) ) {
$value_result = "NotOK";
}
elsif ( ( $type_result eq "PASS" ) ) {
$value_result = "OK";
}
elsif ( $type_result eq "WARNING" ) {
$value_result = "WARR";
}
else {
$value_result = "UNDEF";
}
$test_result[$num] = $value_result;
$num = $num + 1;
}
if ( @test_result == grep { $_ eq "OK" } @test_result ) {
$value_result_end = "OK";
}
elsif ( grep { $_ eq 'NotOK' } @test_result ) {
$value_result_end = "NotOK";
}
elsif ( grep { ( $_ eq 'WARR' ) } @test_result ) {
$value_result_end = "WARR";
}
else {
$value_result_end = "UNDEF";
}
# print "$value_result_end";
$writer->startTag( "result", "state" => "$value_result_end" );
$writer->characters( "\n" );
$writer->startTag( "description", "href" => "$xmlFile" );
$writer->characters( "\n" );
$writer->startTag( "description" );
$writer->characters( "\n" );
$writer->cdata( $xmlFile );
$writer->characters( "\n" );
$writer->endTag( "description" );
$writer->endTag( "description" );
$writer->endTag( "result" );
}
$writer->endTag( "test" );
$writer->characters( "\n" );
}
###****************************************************************
$writer->endTag( "test" );
$writer->characters( "\n" );
$writer->endTag( "Summary" );
$writer->end();
$output->close();
}
###****************************************************************
&WriteXML( $dir );
system( "summary.xml" );
如上所述,读取XML文件的目录是另一个驱动器(此处为D:\
)。如果我将所有XML文件放在Perl代码所在的同一文件夹中,那么效果很好但是我有错误:
无法为文件“test.xml”创建文件解析器上下文:test.pl第46行的不适当的I / O控制操作。
请您告诉我哪里遗漏了导致错误的内容?
答案 0 :(得分:-1)
我道歉。我以为我已经回答了这个问题,因为你用完整的代码更新了它。我想我输入了它并将其丢弃
问题在于行
my @testFile = <*.xml>
在 chdir
之前执行到目录。要解决此问题,只需在子程序中的chdir
之后将该行移至
虽然我们正在使用它,但您将目录路径传递给子例程但未使用它。你应该写点像
my ($dir) = @_;
chdir $dir;
my @testFile = <*.xml>;
您还应该在程序顶部use autodie
,它会自动捕获文件IO中的任何错误,例如open
,close
,chdir
等。在每个
or die $!
如果我将所有XML文件放在与perl代码相同的文件夹中,那么效果很好
出于多种原因,我不认为您发布的代码可以正常工作,无论您放置XML数据文件的位置如何。以下是您需要解决的一些问题
您不能use XML::Writer
任何地方
您不能致电WriteXML
错误发生在程序的第144行,但该代码只有三十行
您打开test.xml
输出但从未关闭它,因此在您使用XML::LibXML
您所编写的数据仅为<Summary><test name="test">
,没有结束标记,因此它将是无效的XML文件
即使你的数据被写入并且元素被正确关闭,你的代码也会查找XPath /sr:SquishReport/sr:test/sr:test
,它与文件中的数据完全不同,所以它会失败