use strict; use warnings; use XML::Simple; use Data::Dumper; $Data::Dumper::Useqq = 1; $Data::Dumper::Sortkeys = 1; $Data::Dumper::Indent = 0; my $xml1 = XMLin("test1.xml",ForceArray => 1, KeyAttr => [],ValueAttr => [],KeepRoot => 1) or die("Error: Cannot load XML1 ($!)"); my $xml2 = XMLin("test2.xml",ForceArray => 1, KeyAttr => [],ValueAttr => [],KeepRoot => 1) or die("Error: Cannot load XML2 ($!)"); my @Differences; ### # wir arbeiten uns durch den Baum: my @stack=({path => 'ROOT', childs1 => [$xml1], childs2 => [$xml2] }); while(@stack) { my $elm = shift(@stack); my $cnt = -1; if(ref($elm->{childs1}) eq 'ARRAY') { if(!ref($elm->{childs2}) eq 'ARRAY') { push(@Differences,"In $elm->{path} XML1 hat Kinder XML2 nicht!"); next; } if($#{$elm->{childs1}} != $#{$elm->{childs2}}) { push(@Differences,"In $elm->{path} Kinder haben unterschiedliche Anzahl"); } for my $child1 (@{$elm->{childs1}}) { my $child2 = $elm->{childs2}->[++$cnt]; unless($child2) { push(@Differences,"In $elm->{path}[$cnt] aus XML1 hat keinen Partner in XML2"); next; } if(ref($child1) eq 'HASH') { for my $key (sort keys(%$child1)) { if(!exists($child2->{$key})) { push(@Differences,"In $elm->{path}[$cnt]/$key aus XML1 hat keine entsprechung in XML2"); next(); } my $c1 = $child1->{$key}; my $c2 = $child2->{$key}; # Spezialbehandlung für "Parameter" # Die Attribute "name" und "value" bestimmen den Inhalt. if($key eq 'Parameter') { my $ok = 0; my %e2; for my $elm (@$c2) { next if(!defined($elm->{name})); next if(!defined($elm->{value})); $e2{$elm->{name}} = $elm->{value}; } my $c = -1; for my $e1 (@$c1) { $c++; next if(!defined($e1->{name})); next if(!defined($e1->{value})); $ok++; push(@stack,{path => $elm->{path}.qq([$cnt]/$key).qq([$c] name=").$e1->{name}.qq("/value), childs1 => $e1->{value}, childs2 => $e2{$e1->{name}} }); } # wenn das Aktiv ist wird die Reihenfolge der "Parameter" nicht geprüft #next if($ok); } if(ref($c1) and ref($c1) eq ref($c2) and ref($c1) ne 'ARRAY') { $c1 = [ $c1 ]; $c2 = [ $c2 ]; } push(@stack,{path => $elm->{path}."[$cnt]/$key", childs1 => $c1, childs2 => $c2 }) } next; } if(Dumper($child1) ne Dumper($child2)) { push(@Differences,"In $elm->{path}[$cnt] aus XML1 hat einen anderen Wert als XML2 ($child1 <> $child2)"); } } next; } if(Dumper($elm->{childs1}) ne Dumper($elm->{childs2})) { push(@Differences,"In $elm->{path} aus XML1 hat einen anderen Wert in XML2 ($elm->{childs1} <> $elm->{childs2})"); } } open(my $fh, '>', "result.txt") or die("ERROR open ($!)"); if(@Differences) { print $fh join("\n",@Differences); } else { print $fh "Datei XML2 hat die selben Einträge wie XML1\n"; } close($fh);