×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Jobs

Use of uninitialized value in substitution (s///) error

Use of uninitialized value in substitution (s///) error

Use of uninitialized value in substitution (s///) error

(OP)
I'm new to Perl, just trying to create an xml file from a csv file:

CODE

{
my($fi) = $ARGV[0];
my($fo) = $ARGV[1];
my(@fields);
my(@fieldHeaders);
my($row);
my($i_count)=1;
my($ii_count)=0;
my($string);


sub trim($)
{
	$string = shift;
	$string =~ s/^\s+//;
	$string =~ s/\s+$//;
	$string =~ s/\s+//g;
	$string =~ s/\///g;
	return $string;
}

open(FI,$fi) || die("Cannot open $fi as input.\n");
open(FO,">$fo") || die("Cannot open $fo as output.\n");

print FO "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<RESULT>\n";

while ($row=<FI>)
	{
		chop($row);
		@fields = split(/,/,$row);

		if($i_count==1)
		{
		@fieldHeaders = split(/,/,$row);
		}


		if($i_count!=1)
		{
		print FO "<item>\n";
			foreach (@fieldHeaders)
			{
				print FO "<".trim($fieldHeaders[$ii_count]).">".trim($fields[$ii_count])."</".trim($fieldHeaders[$ii_count]).">\n";
				$ii_count=$ii_count+1;
			}

	        print FO "</item>\n";
		}
		$ii_count=0;
		$i_count=$i_count+1;
	}
print FO "</RESULT>\n";
close(FO);
close(FI);

} 


The input file is of this format:

CODE

// field 1, field 2, field 3
value1, value2, value3 

This is the error:

CODE

Use of uninitialized value in substitution (s///) at D:\quic_shares_cr_prod\Releases\Library\v3.1.20\MeanReversionToXML.pl line 15, <FI> line 873.
Use of uninitialized value in substitution (s///) at D:\quic_shares_cr_prod\Releases\Library\v3.1.20\MeanReversionToXML.pl line 16, <FI> line 873.
Use of uninitialized value in substitution (s///) at D:\quic_shares_cr_prod\Releases\Library\v3.1.20\MeanReversionToXML.pl line 17, <FI> line 873.
Use of uninitialized value in substitution (s///) at D:\quic_shares_cr_prod\Releases\Library\v3.1.20\MeanReversionToXML.pl line 18, <FI> line 873.
Use of uninitialized value in concatenation (.) or string at D:\quic_shares_cr_prod\Releases\Library\v3.1.20\MeanReversionToXML.pl line 43, <FI> line 873.
Use of uninitialized value in substitution (s///) at D:\quic_shares_cr_prod\Releases\Library\v3.1.20\MeanReversionToXML.pl line 15, <FI> line 873.
Use of uninitialized value in substitution (s///) at D:\quic_shares_cr_prod\Releases\Library\v3.1.20\MeanReversionToXML.pl line 16, <FI> line 873.
Use of uninitialized value in substitution (s///) at D:\quic_shares_cr_prod\Releases\Library\v3.1.20\MeanReversionToXML.pl line 17, <FI> line 873.
Use of uninitialized value in substitution (s///) at D:\quic_shares_cr_prod\Releases\Library\v3.1.20\MeanReversionToXML.pl line 18, <FI> line 873.
Use of uninitialized value in concatenation (.) or string at D:\quic_shares_cr_prod\Releases\Library\v3.1.20\MeanReversionToXML.pl line 43, <FI> line 873.
Use of uninitialized value in substitution (s///) at D:\quic_shares_cr_prod\Releases\Library\v3.1.20\MeanReversionToXML.pl line 15, <FI> line 873.
Use of uninitialized value in substitution (s///) at D:\quic_shares_cr_prod\Releases\Library\v3.1.20\MeanReversionToXML.pl line 16, <FI> line 873.
Use of uninitialized value in substitution (s///) at D:\quic_shares_cr_prod\Releases\Library\v3.1.20\MeanReversionToXML.pl line 17, <FI> line 873.
Use of uninitialized value in substitution (s///) at D:\quic_shares_cr_prod\Releases\Library\v3.1.20\MeanReversionToXML.pl line 18, <FI> line 873.
Use of uninitialized value in concatenation (.) or string at D:\quic_shares_cr_prod\Releases\Library\v3.1.20\MeanReversionToXML.pl line 43, <FI> line 873.
Use of uninitialized value in substitution (s///) at D:\quic_shares_cr_prod\Releases\Library\v3.1.20\MeanReversionToXML.pl line 15, <FI> line 873.
Use of uninitialized value in substitution (s///) at D:\quic_shares_cr_prod\Releases\Library\v3.1.20\MeanReversionToXML.pl line 16, <FI> line 873.
Use of uninitialized value in substitution (s///) at D:\quic_shares_cr_prod\Releases\Library\v3.1.20\MeanReversionToXML.pl line 17, <FI> line 873.
Use of uninitialized value in substitution (s///) at D:\quic_shares_cr_prod\Releases\Library\v3.1.20\MeanReversionToXML.pl line 18, <FI> line 873.
Use of uninitialized value in concatenation (.) or string at D:\quic_shares_cr_prod\Releases\Library\v3.1.20\MeanReversionToXML.pl line 43, <FI> line 873. 

Can anyone point me in the right direction to resolve the error ?

Thanks in advance

Simon

RE: Use of uninitialized value in substitution (s///) error

Hey,

Your code needs some critical adjustments.

The key issue you identified is caused by the fact that you are passing an undefined value to the trim() function. The codes current logic suggests that it would be impossible for a defined value ever to be passed to the trim() function.

While iterating the data, you assign @fieldHeaders only if $i_count is equal to "1". Beneath that, you execute the code that uses @fieldHeaders, if $i_count is not equal to "1", therefore @fieldHeaders will always be undefined when used.

Other issues:
- You don't make use of @fields (the actual data). I believe you meant to in places where @fieldHeaders is used. Due to this, its difficult to conceive what XML output you truly desire.
- Always use strict and warnings.
- The trim() function doesn't look right. You remove leading and trailing spaces, then lead onto remove all spaces anyway. Also, the removal of forward slashes doesn't suitably belong to a function named trim.
- My preference is to use the three way argument form of open with a lexical var filehandle.
- You probably meant to use chomp over chop. At the moment, if the last character of your input file isn't a new line, it will remove it anyway.
- You are combining the use of control loops and index counters unnecessarily / incorrectly. Specifically, there is no need for an index counter within the foreach loop. $_ already contains the current element, but its better to assign your own var.
- It looks as though your input data is in CSV format. It might be better to use a CSV module such as Text::CSV to handle.
- Its best to use one of the many modules available to write the XML for you, for many advantageous reasons. These include XML::Writer or even XML::Simple.

I would write an improved example, but as explained above, i'm uncertain of your desired output. I hope you are able to use the above to improve / fix your code.

Thanks,

Chris

RE: Use of uninitialized value in substitution (s///) error

I had nothing better to do therefore thought I would write an example big smile. Depending on the situation, my usual preference is to use Template Toolkit to generate XML / handle i.e. escaping myself, but XML Writer does the job here.

CODE

#! /usr/bin/perl
use strict;
use warnings;
use IO::File;
use Text::CSV;
use XML::Writer;

my ($csv_input_path, $xml_output_path) = @ARGV;

##########
# create objects.

my $xml_output_fh = IO::File->new( ">$xml_output_path" );
my $csv_input_fh = IO::File->new( "<$csv_input_path" );

my $xml_writer = new XML::Writer( OUTPUT => $xml_output_fh );

my $text_csv = Text::CSV->new ( { binary => 1 } ) or die Text::CSV->error_diag();
$text_csv->column_names( map { trim( $_ ) } @{$text_csv->getline( $csv_input_fh )} );

##########
# main.

$xml_writer->xmlDecl( 'UTF-8' );
$xml_writer->startTag( 'people' );
while ( my $row = $text_csv->getline_hr( $csv_input_fh ) )
{
	$xml_writer->startTag( 'person' );
	while ( my ($column, $value) = each ( %$row ) )
	{
		$xml_writer->startTag( $column );
		$xml_writer->characters( trim( $value ) );
		$xml_writer->endTag( $column );
	}
	$xml_writer->endTag( 'person' );
}
$xml_writer->endTag( 'people' );

##########
# kill objects.

$text_csv->eof or $text_csv->error_diag();

$xml_writer->end();

$csv_input_fh->close();
$xml_output_fh->close();

##########

sub trim
{
	my $v = shift;
	$v =~ s/^\s+//;
	$v =~ s/\s+$//;
	return $v;
} 

Chris

RE: Use of uninitialized value in substitution (s///) error

Last thing,

I hadn't read your prints properly, and noticed you are indeed making use of @fields, therefore ignore my comments regarding. My example generates XML in the same format you desire (although no sorting).

Chris

RE: Use of uninitialized value in substitution (s///) error

Update to suit your requirements:

CODE

#! /usr/bin/perl
use strict;
use warnings;
use IO::File;
use Text::CSV;
use XML::Writer;

my $groups_node = 'RESULT';
my $group_node  = 'item';

my ($csv_input_path, $xml_output_path) = @ARGV;

##########
# create objects.

my $xml_output_fh = IO::File->new( ">$xml_output_path" );
my $csv_input_fh = IO::File->new( "<$csv_input_path" );

my $xml_writer = new XML::Writer( OUTPUT => $xml_output_fh );

my $text_csv = Text::CSV->new ( { binary => 1 } ) or die Text::CSV->error_diag();
$text_csv->column_names( $text_csv->getline( $csv_input_fh ) );

##########
# main.

$xml_writer->xmlDecl( 'UTF-8' );
$xml_writer->startTag( $groups_node );
while ( my $row = $text_csv->getline_hr( $csv_input_fh ) )
{
	$xml_writer->startTag( $group_node );
	while ( my ( $column, $value ) = each ( %$row ) )
	{
		$xml_writer->startTag( clean_column( $column ) );
		$xml_writer->characters( clean_value( $value ) );
		$xml_writer->endTag( clean_column( $column ) );
	}
	$xml_writer->endTag( $group_node );
}
$xml_writer->endTag( $groups_node );

##########
# kill objects.

$text_csv->eof or $text_csv->error_diag();

$xml_writer->end();

$csv_input_fh->close();
$xml_output_fh->close();

##########

sub clean_column
{
	my $c = shift;
	$c =~ s/\s+//g;
	$c = lc $c;
	return $c;
}

sub clean_value
{
	my $v = shift;
	$v =~ s/^\s+//;
	$v =~ s/\s+$//;
	return $v;
} 

RE: Use of uninitialized value in substitution (s///) error

(OP)
Thanks - it's working without error now.

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close