Finance-OFX
view release on metacpan or search on metacpan
lib/Finance/OFX/Parse.pm view on Meta::CPAN
if( ref($tree) eq 'ARRAY' )
{
parse_dates($_) for @{$tree};
}
elsif( ref($tree) eq 'HASH' )
{
for( keys %{$tree} )
{
if( /^dt/ )
{
# Add seconds spacer
$tree->{$_} =~ s/^([0-9]{12})([0-9]{2})/$1:$2/;
# Add minutes spacer
$tree->{$_} =~ s/^([0-9]{10})([0-9]{2})/$1:$2/;
# Add date spacers
$tree->{$_} =~ s/^([0-9]{4})([0-9]{2})([0-9]{2})/$1-$2\-$3 /;
# Add a leading zero to the timezone offset, if needed
$tree->{$_} =~ s/\[([-+]?)([0-9]):[A-Z]{3}\]/ $1\x30$2\x30\x30/;
# Handle timezone offsets that were already 2 digits
$tree->{$_} =~ s/\[([-+]?)([0-9]{1,2}):[A-Z]{3}\]/ $1$2\x30\x30/;
# Do the conversion
$tree->{$_} = str2time($tree->{$_}, 'GMT');
}
else
{
parse_dates($tree->{$_});
}
}
}
}
sub parse
{
$_[0] =~ s/\x0D//g; # Un-networkify newlines
my ($header, $body) = split /\n\n/, shift, 2;
# Parse the OFX header block
$header =~ s/^\s//; # Strip leading whitespace
my %header = split /[:\n]/, $header; # Convert to a hash
return undef unless ($header{OFXHEADER} == '100') and ($header{DATA} eq 'OFXSGML');
my $tree = Finance::OFX::Tree::parse($body);
return undef unless $tree and ($tree->[0]{name} eq 'ofx');
$tree = collapse($tree); # Collapse the parse tree into a hash
parse_dates($tree); # Convert date elements to Unix time
# Merge the header hash into the parse tree
$tree->{header} = \%header;
return $tree;
}
sub parse_file
{
my $file = shift;
return undef unless $file;
# my $text = do { local(@ARGV, $/) = $file; <> };
my $text = read_file($file);
return undef unless $text;
return parse($text);
}
1;
__END__
=head1 NAME
Finance::OFX::Parse - Parse the Open Financial Exchange protocol
=head1 SYNOPSIS
use Finance::OFX::Parse
my $tree = Finance::OFX::Parse::parse($ofxContent);
=head1 DESCRIPTION
C<Finance::OFX::Parse> provides two functions, C<parse()> and C<parse_file()>, that
accept an OFX "file" and return a reference to a hash tree representing the
contents of the file. C<parse()> expects the OFX content as a scalar argument
while C<parse_file> expects a filename.
Parsing well-formed OFX content returns a hash with two keys: 'ofx' and
'header'. The 'ofx' key is a reference to a hash tree representing the <OFX> block
and the 'header' key is a reference to a hash of header attributes. All date
values are automatically converted to UNIX time.
=head2 EXAMPLE
If C<$ofxContent> in the above code is...
OFXHEADER:100
DATA:OFXSGML
VERSION:102
SECURITY:NONE
ENCODING:USASCII
CHARSET:1252
COMPRESSION:NONE
OLDFILEUID:NONE
NEWFILEUID:NONE
<OFX>
<SIGNONMSGSRSV1>
<SONRS>
<STATUS>
<CODE>0
<SEVERITY>INFO
<MESSAGE>SonRq is successful
</STATUS>
<DTSERVER>20080220142819.321[-8:PST]
<LANGUAGE>ENG
<FI>
<ORG>DI
<FID>074014187
</FI>
</SONRS>
</SIGNONMSGSRSV1>
( run in 1.317 second using v1.01-cache-2.11-cpan-800906f7e73 )