E
Eric van Oorschot
Hi,
I'm writing a Perl script that has to copy a block of data (nodes numbers
and coordinates) from one XML formatted file into another XML file.
I'm using XML:arser to extract the data and XML::Writer to write the
data into the second file.
This does not work, since some of the numbers are corrupted after being
read by XML:arser. Below I have copied a small bit that shows how the
data is corrupted. It always happens at the same line(s) of data.
67 2.9005093479606E+000 3.6637104002418E-001 7.9522656092442E-001
68 2.8852994122583E+000 3.5353599488296E-001 7.7516591265738E-001
69 2.9109259023248E+000 3.5272037818926E-001 8.1765470045
602E-001
70 2.9014248453522E+000 3.4032368974452E-001 7.9417266267164E-001
71 2.8849923984542E+000 3.2706829720117E-001 7.7537618002780E-001
My Perl script (I am not an experienced Perl programmer) is shown below.
The error occurs in the sub 'ReadCharacterData'. In this subroutine the
data is read and copied into a hash %tables. When writing this hash in the
output file the error shown above is found.
If anyone has an idea, or needs more info, please reply.
Regards,
Eric
use XML:arser;
use IO::File;
use Switch ;
use XML::Writer;
my $fmsfile = shift ; # fms output file
my $reffile = shift ; # Exchange output deck
my $outfile = shift ; # Output file
die "Cannot find fms output file \"$xmlfile\""
unless -f $fmsfile;
die "Cannot find xml input deck \"$reffile\""
unless -f $reffile;
my $output = new IO::File(">$outfile");
my $writer = new XML::Writer( OUTPUT => $output, UNSAFE => 1 );
#
# Find tmax in fms file
#
my $tmax = 0.00 ;
open ( IN, $fmsfile ) ;
while ( <IN> ) {
if ( /TIME/ ) {
( $dum, $dum, $dum, $ti ) = split /\s+/ ;
$tmax = $ti if ( $ti > $tmax ) ;
}
}
close (IN) ;
$tag = "";
my %tables ; # hash with coordinates from fms file
my $model ; # naam van het FE model
my $i = 0 ; #
# Readfile to create hash of the coordinate tables
#
my $parser = new XML:arser;
$parser->setHandlers( Char => \&ReadCharacterData,
Default => \&default);
print "Reading fms file ($fmsfile)\n" ; $parser->parsefile($fmsfile);
## Check info read in fms file
#foreach $i ( keys %tables ) {
# print "Table $i\n",$tables{$i},"\n End table $i\n\n";
# }
my $coords = 0 ;
#
# Read reffile and replace coordinate tables with data from fms file
#
my $bparser = new XML:arser;
$bparser->setHandlers( XMLDecl => \&XmlDecl,
Doctype => \&DocType,
Start => \&startElement,
End => \&endElement,
Char => \&characterData,
CdataStart => \&cdatastart,
CdataEnd => \&cdataend,
Default => \&default);
print "Reading ($reffile) and writing ($outfile) \n" ;
$bparser->parsefile($reffile);
$writer->end() ;
#
########################################################################
#
sub XmlDecl {
my( $parseinst, $version, $encoding, $standalone ) = @_;
$writer->xmlDecl( $encoding, $standalone );
}
sub DocType {
my( $parseinst, $name, $sysid, $pub, $internal ) = @_;
$writer->doctype( $name, $pub, $sysid );
}
sub startElement {
# Reading xml data
my( $parseinst, $element, %attrs ) = @_;
SWITCH: {
if ($element eq "FE_MODEL") {
$model = $attrs{'NAME'} ;
$tag = "DEFINE";
# print "FE model $model\n" ;
last SWITCH;
}
if ($element eq "TABLE" && $attrs{'TYPE'} =~ /COORDINATE/ ) {
$coords = 1 ;
# print "$coords - TABLE COORDINATES\n" ;
}
last SWITCH ;
}
$writer -> startTag( $element , %attrs );
}
sub endElement {
my( $parseinst, $element ) = @_;
$coords = 0 ;
$writer -> endTag( $element ) ;
}
sub ReadCharacterData {
my( $parseinst, $data ) = @_;
SWITCH: {
if ( $data =~ /^\s*$/ ) {
last ;
};
if ( $data =~ /TIME/ ) {
( $dum, $dum, $dum, $ti ) = split /\s+/, $data ;
# print "Timepoint ", $ti, "\n" ;
last ;
} ;
if ( $data =~ /FE MODEL/ ) {
($dum, $dum, $dum, $dum, $dum ) = split /\s+/, $data ;
( $txt = $dum ) =~ s/\/.*\/// ; # strip system numbering
# print $txt, "\n" ;
$tables{$txt} = ' ' ;
last ;
} ;
if ( $ti == $tmax ) {
# print $data ;
$tables{$txt} .= $data . "\n" ;
last ;
} ;
}
}
sub characterData {
my( $parseinst, $data ) = @_;
if ( $writer->within_element('FE_MODEL') && $writer->within_element('TABLE') && $coords && $data != /^\s*$/ ) {
$writer -> characters ( $tables{$model} ) ;
$tables{$model} = ' ' ; #empty table
}
elsif ( ! $coords ) {
# print "Coords $coords : $data";
$writer -> characters( $data ) ;
}
}
sub cdatastart {
$writer -> raw( "<![CDATA[\n" );
}
sub cdataend {
$writer -> raw( "]]>\n" );
}
sub default {
# do nothing, but stay quiet
}
I'm writing a Perl script that has to copy a block of data (nodes numbers
and coordinates) from one XML formatted file into another XML file.
I'm using XML:arser to extract the data and XML::Writer to write the
data into the second file.
This does not work, since some of the numbers are corrupted after being
read by XML:arser. Below I have copied a small bit that shows how the
data is corrupted. It always happens at the same line(s) of data.
67 2.9005093479606E+000 3.6637104002418E-001 7.9522656092442E-001
68 2.8852994122583E+000 3.5353599488296E-001 7.7516591265738E-001
69 2.9109259023248E+000 3.5272037818926E-001 8.1765470045
602E-001
70 2.9014248453522E+000 3.4032368974452E-001 7.9417266267164E-001
71 2.8849923984542E+000 3.2706829720117E-001 7.7537618002780E-001
My Perl script (I am not an experienced Perl programmer) is shown below.
The error occurs in the sub 'ReadCharacterData'. In this subroutine the
data is read and copied into a hash %tables. When writing this hash in the
output file the error shown above is found.
If anyone has an idea, or needs more info, please reply.
Regards,
Eric
use XML:arser;
use IO::File;
use Switch ;
use XML::Writer;
my $fmsfile = shift ; # fms output file
my $reffile = shift ; # Exchange output deck
my $outfile = shift ; # Output file
die "Cannot find fms output file \"$xmlfile\""
unless -f $fmsfile;
die "Cannot find xml input deck \"$reffile\""
unless -f $reffile;
my $output = new IO::File(">$outfile");
my $writer = new XML::Writer( OUTPUT => $output, UNSAFE => 1 );
#
# Find tmax in fms file
#
my $tmax = 0.00 ;
open ( IN, $fmsfile ) ;
while ( <IN> ) {
if ( /TIME/ ) {
( $dum, $dum, $dum, $ti ) = split /\s+/ ;
$tmax = $ti if ( $ti > $tmax ) ;
}
}
close (IN) ;
$tag = "";
my %tables ; # hash with coordinates from fms file
my $model ; # naam van het FE model
my $i = 0 ; #
# Readfile to create hash of the coordinate tables
#
my $parser = new XML:arser;
$parser->setHandlers( Char => \&ReadCharacterData,
Default => \&default);
print "Reading fms file ($fmsfile)\n" ; $parser->parsefile($fmsfile);
## Check info read in fms file
#foreach $i ( keys %tables ) {
# print "Table $i\n",$tables{$i},"\n End table $i\n\n";
# }
my $coords = 0 ;
#
# Read reffile and replace coordinate tables with data from fms file
#
my $bparser = new XML:arser;
$bparser->setHandlers( XMLDecl => \&XmlDecl,
Doctype => \&DocType,
Start => \&startElement,
End => \&endElement,
Char => \&characterData,
CdataStart => \&cdatastart,
CdataEnd => \&cdataend,
Default => \&default);
print "Reading ($reffile) and writing ($outfile) \n" ;
$bparser->parsefile($reffile);
$writer->end() ;
#
########################################################################
#
sub XmlDecl {
my( $parseinst, $version, $encoding, $standalone ) = @_;
$writer->xmlDecl( $encoding, $standalone );
}
sub DocType {
my( $parseinst, $name, $sysid, $pub, $internal ) = @_;
$writer->doctype( $name, $pub, $sysid );
}
sub startElement {
# Reading xml data
my( $parseinst, $element, %attrs ) = @_;
SWITCH: {
if ($element eq "FE_MODEL") {
$model = $attrs{'NAME'} ;
$tag = "DEFINE";
# print "FE model $model\n" ;
last SWITCH;
}
if ($element eq "TABLE" && $attrs{'TYPE'} =~ /COORDINATE/ ) {
$coords = 1 ;
# print "$coords - TABLE COORDINATES\n" ;
}
last SWITCH ;
}
$writer -> startTag( $element , %attrs );
}
sub endElement {
my( $parseinst, $element ) = @_;
$coords = 0 ;
$writer -> endTag( $element ) ;
}
sub ReadCharacterData {
my( $parseinst, $data ) = @_;
SWITCH: {
if ( $data =~ /^\s*$/ ) {
last ;
};
if ( $data =~ /TIME/ ) {
( $dum, $dum, $dum, $ti ) = split /\s+/, $data ;
# print "Timepoint ", $ti, "\n" ;
last ;
} ;
if ( $data =~ /FE MODEL/ ) {
($dum, $dum, $dum, $dum, $dum ) = split /\s+/, $data ;
( $txt = $dum ) =~ s/\/.*\/// ; # strip system numbering
# print $txt, "\n" ;
$tables{$txt} = ' ' ;
last ;
} ;
if ( $ti == $tmax ) {
# print $data ;
$tables{$txt} .= $data . "\n" ;
last ;
} ;
}
}
sub characterData {
my( $parseinst, $data ) = @_;
if ( $writer->within_element('FE_MODEL') && $writer->within_element('TABLE') && $coords && $data != /^\s*$/ ) {
$writer -> characters ( $tables{$model} ) ;
$tables{$model} = ' ' ; #empty table
}
elsif ( ! $coords ) {
# print "Coords $coords : $data";
$writer -> characters( $data ) ;
}
}
sub cdatastart {
$writer -> raw( "<![CDATA[\n" );
}
sub cdataend {
$writer -> raw( "]]>\n" );
}
sub default {
# do nothing, but stay quiet
}