-4

I am using the first answer to Extracting data from an XML document that uses namespaces to create an XML file using Perl.

Here is my code:

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" );

As it is mentioned, the directory for reading XML files is another drive (here D:\). If I put all XML files in the same folder where Perl code is then works great but otherwise I have the error:

Could not create file parser context for file "test.xml": Inappropriate I/O control operation at test.pl line 46.

Would you please let me know where I am missing something that causes error?

Community
  • 1
  • 1
Royeh
  • 433
  • 5
  • 21
  • Re "XML::LibXML->load: specify location, string, or IO at 8.pl line 144.", There aren't 144 lines in that program. Please post the output you actually got!!!! – ikegami Nov 02 '15 at 13:22
  • @ikegami Now I have added the whole code!! – Royeh Nov 02 '15 at 14:50
  • You made things worse! Use the *minimal* amount of code to demonstrate your problem, and your output still doesn't match up with the code you posted. – ikegami Nov 02 '15 at 14:50
  • There was an edition by another person and then it is not the exact line which I have written. – Royeh Nov 02 '15 at 14:59

1 Answers1

-1

Update

I apologise. I thought I had answered this question since you updated it with your full code. I guess I typed it up and discarded it by mistake

The problem is that the line

my @testFile = <*.xml>

is executed before your chdir to the directory. To fix it, just move that line to after the chdir within the subroutine

And while we're at it, you are passing the directory path to the subroutine but not using it. You should write something like

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

You should also use autodie at the top of the program, which will automatically catch any errors from file IO like open, close, chdir etc. Without you having to code or die $! on each one


Original response

If I put all XML files in the same folder as perl code is then works great

For a number of reasons, I don't think the code you have posted can work at all, regardless of where you place the XML data file. Here are some things you need to fix

  • You don't use XML::Writer anywhere

  • You don't call WriteXML

  • The error is on line 144 of your program, but that code is only thirty lines long

  • You open test.xml for output but never close it, so the data is probably not written to the file before you read it with XML::LibXML

  • The data you are writing is just <Summary><test name="test"> with no closing tags, so it would be an invalid XML file

  • Even if your data was written and the elements were closed properly, your code then looks for the XPath /sr:SquishReport/sr:test/sr:test which is nothing like the data in the file so it will fail

Borodin
  • 126,100
  • 9
  • 70
  • 144
  • Thanks for your answer. Well, I am sure it works fine and now you may find the whole code as edited version!! – Royeh Nov 02 '15 at 13:39