错误:XML :: LibXML-> load:在8.pl第144行指定位置,字符串或IO

时间:2015-11-02 06:47:42

标签: xml perl xml-libxml

我正在使用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控制操作。

请您告诉我哪里遗漏了导致错误的内容?

1 个答案:

答案 0 :(得分:-1)

更新

我道歉。我以为我已经回答了这个问题,因为你用完整的代码更新了它。我想我输入了它并将其丢弃

问题在于行

my @testFile = <*.xml>

chdir之前执行到目录。要解决此问题,只需在子程序中的chdir之后将该行移至

虽然我们正在使用它,但您将目录路径传递给子例程但未使用它。你应该写点像

my ($dir) = @_;
chdir $dir;
my @testFile = <*.xml>;

您还应该在程序顶部use autodie,它会自动捕获文件IO中的任何错误,例如openclosechdir等。在每个

上编码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,它与文件中的数据完全不同,所以它会失败