DeductionPro is a software package that is used by many U.S. residents to help determine the value of items donated to charity. Unfortunately, the UI does not provide a good search function and finding items within the hierarchical tree of categories can be tedious. It did not take me long to get frustrated enough to take matters into my own hands (with a bit of Perl, of course).
The data file used by the program is a simple, albeit awkward, XML file. I sprinkled a bit of XML::Twig over it and produced a tab-separated text file that can be searched more easily.
I'm quite sure there is a more efficient, or at least more Perl-ish, way of doing this. I'd be interested in other approaches, especially since I'm not very familiar with Twig.
use strict; use warnings; use XML::Twig; # Could specify $infile in @ARGV, but this is a specialized use case my $infile = 'DPNoncashDetails.xml'; #************************************************* open( my $outfh, '>', $infile . '.txt' ) or die $!; my %data; # holds item and pricing data my $twig = XML::Twig->new( start_tag_handlers => { Item => \&item } ); $twig->parsefile( $infile ); my @fields = ( 'name', 'Like New', 'Minor Wear', 'Average Wear' ); print $outfh '# ', join( "\t", 'Category', @fields ), "\n"; foreach my $treestr ( sort { $a cmp $b } keys %data ) { my $h = $data{$treestr}; foreach my $id ( sort { $h->{$a}{name} cmp $h->{$b}{name} } keys % +$h ) { print $outfh join( "\t", $treestr, @{ $h->{$id} }{ @fields } ) +, "\n"; } } #************************************************* sub item { my ( $twig, $elt ) = @_; my $tree = get_category_tree( $elt ); $tree = join( " => ", @$tree ); my $href = $elt->atts; verify_id( $tree, $href ); $data{$tree}{ $href->{itemNum} }{name} = $href->{name}; $data{$tree}{ $href->{itemNum} }{ $href->{quality} } = $href->{fmv +}; } sub get_category_tree { my ( $elt ) = @_; my @tree; while( my $parent = $elt->parent ) { last if $parent->tag eq 'NonCashDetails'; next if $parent->tag ne 'Category'; unshift( @tree, $parent->att('name') ); $elt = $parent; } return \@tree; } sub verify_id { my ( $tree, $href ) = @_; my $id = $href->{itemNum}; my $name = $href->{name}; if( exists $data{$tree} && exists $data{$tree}{$id} ) { if( $name ne $data{$tree}{$id}{name} ) { print "Warning: about to overwrite data due to record mism +atch\n"; print " $tree, item id = $id:\n"; print " [existing]: $data{$tree}{$id}{name}\n"; print " [new]: $name\n"; } } }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Reformat DeductionPro 2008 Data File
by dHarry (Abbot) on Mar 30, 2009 at 06:40 UTC | |
by bobf (Monsignor) on Mar 31, 2009 at 01:55 UTC | |
|
Re: Reformat DeductionPro 2008 Data File
by Anonymous Monk on Apr 02, 2009 at 04:07 UTC |