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"; } } }
In reply to Reformat DeductionPro 2008 Data File by bobf
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |