#!/usr/bin/env perl # # ndependxml2csv - convert NDepend CQL query results exported as XML # to CSV format # # $Id$ use warnings; use strict; use Getopt::Std; use XML::LibXML; use Text::CSV_XS; my %opt; getopts( 'ht:', \%opt ); my $sep = $opt{'t'} // ','; if ( $opt{'h'} ) { print STDERR <pedantic_parser(1); my $xpc = new XML::LibXML::XPathContext; sub find { $xpc->find(@_)->get_nodelist; } sub findvalues { map { $_->textContent } &find(@_); } my $csv = new Text::CSV_XS( { sep_char => $sep, eol => $/, quote_char => '' } ) or die "the CSV emitter doesn't work (not installed?)\n"; sub nametouse { my ($node) = @_; my ( $name, $fullname ) = map { $node->getAttribute($_) } ( 'Name', 'FullName' ); ( index( $fullname, $name ) >= 0 ) # $name occurs in $name ? $fullname : ( $fullname eq 'Stat' ) ? $name : "$fullname:$name"; } foreach my $srcdoc ( @ARGV ? @ARGV : ('-') ) { my $doc; eval { $doc = $parser->parse_file($srcdoc) }; if ($@) { my $erroron1line = join( ' ', grep { !/^\^ at / } split( /[\r\n]+/, $@ ) ); warn "cannot parse $srcdoc, skipped: $erroron1line\n"; next; } my $root = $doc->getDocumentElement or next; foreach my $query ( &find( '//Query', $root ) ) { # print the header $csv->print( *STDOUT, [ 'query name', &findvalues( 'Columns/Column', $query ) ] ); my $queryname = $query->getAttribute('Name'); # print the content rows, using FullName and Val, ignoring Name foreach my $row ( &find( 'Rows/Row', $query ) ) { $csv->print( *STDOUT, [ $queryname, &nametouse($row), &findvalues( 'Val', $row ) ] ); } } }