2011-01-06 10 views
0

Ich bin ein Anfänger für Perl und CPAN ModulePerl XML konvertieren Lösung

I umwandeln möchte eine XML-Datei enthalten:

<Item><Link>http://example.com/</Link></Item>.... 

Um

<Item><Link>http://mysite.com/</Link></Item>.... 

Haben Sie intelligente Lösungen haben? mit CPAN Modul

Antwort

3
  • siehe XML::Twig - Einer Perl-Modul große XML-Dokumente in Baum-Modus für die Verarbeitung.
  • oder XML::Simple - Easy API XML zu erhalten (esp Konfigurationsdateien)

wie

use strict; 
use warnings; 
use XML::Simple; 
use Data::Dumper; 

my $xml = q~<?xml version='1.0'?> 
<root> 
    <Item> 
    <Link>http://example.com/</Link> 
    </Item> 
    <Item> 
    <Link>http://example1.com/</Link> 
    </Item> 
</root>~; 

print $xml,$/; 

my $data = XMLin($xml); 

print Dumper($data); 

foreach my $test (@{$data->{Item}}){ 
    foreach my $key (keys %{$test}){ 
     $test->{$key} =~ s/example/mysite/; 
    } 
} 
print XMLout($data, RootName=>'root', NoAttr=>1,XMLDecl => 1); 

Ausgang:

<?xml version='1.0'?> 
<root> 
    <Item> 
    <Link>http://example.com/</Link> 
    </Item> 
    <Item> 
    <Link>http://example1.com/</Link> 
    </Item> 
</root> 
$VAR1 = { 
      'Item' => [ 
        { 
         'Link' => 'http://example.com/' 
        }, 
        { 
         'Link' => 'http://example1.com/' 
        } 
        ] 
     }; 
<?xml version='1.0' standalone='yes'?> 
<root> 
    <Item> 
    <Link>http://mysite.com/</Link> 
    </Item> 
    <Item> 
    <Link>http://mysite1.com/</Link> 
    </Item> 
</root> 
0

Wenn alles, was Sie brauchen, ist einen bestimmten Wert zu ändern, Sie brauchen nicht wirklich etwas Besonderes, Sie können einfach regexp verwenden:
von der Befehlszeile:

perl -pi -e '[email protected]://example.com/@http://mysite.com/@g' file.xml 

bearbeiten: Hinzufügen vollständige Codeversion:

my $file = '/tmp/test.xml'; 

open IN, "<$file" or die "can't open $file $!"; 
open OUT, ">$file.tmp" or die "can't open $file.tmp $!"; 
foreach (<IN>) { 
    [email protected]://example.com/@http://mysite.com/@g; 
    print OUT $_; 
} 
close(IN); 
close(OUT); 

rename("$file.tmp", "$file") 
+0

+1 für die Angabe einer regulären Ausdrucklösung, die ganz genau weiß, dass die XML-religiösen Fanatiker Sie gnadenlos bestrafen werden! Der Trick, ein aufgeschlossener und nützlicher Systemadministrator zu sein, ist zu wissen, wann eine einfache Lösung zu verwenden ist und wann man das Schwergewicht verwenden sollte (daher haben einige XML-Fans keine Ahnung, dass einfache Lösungen gelegentlich ausreichen). –

+0

Danke :), genau so fühle ich mich bei xml, manchmal braucht man einfach keine vollständige XML-Bibliothek, um so etwas zu ändern. – OneOfOne

+1

Die Sache ist, wir haben nicht viele Informationen über den Rest des XML. Soweit wir wissen, kann es andere Elemente enthalten, die URLs enthalten. Oder sie könnten sie in Zukunft einschließen. Deshalb gebe ich lieber eine Lösung, die in jedem Fall stimmt. – mirod

3

Eine einfache Lösung unter Verwendung von XML :: Twig ist unten. Im Vergleich zur XML :: Simple-Option funktioniert es unabhängig davon, wo sich die Link-Elemente im XML befinden, und es wird die ursprüngliche Formatierung der Datei berücksichtigt. Es funktioniert auch, wenn der XML-Code gemischte Inhalte enthält.

Wenn Sie die Datei an seinem Platz ändern müssen, können Sie parsefile_inplace statt parsefile verwenden, und ich vermute, der reguläre Ausdruck in subs_text kann im wirklichen Leben verbessert werden muß, aber dieser Code sollte ein guter Ausgangspunkt sein.

#!/usr/bin/perl 

use strict; 
use warnings; 

use XML::Twig; 

XML::Twig->new(twig_roots => { Link => \&replace_link, }, # process Link 
       twig_print_outside_roots => 1,    # output everything else 
      ) 
      ->parsefile('my.xml'); 

sub replace_link 
    { my($t, $link)= @_; 
    $link->subs_text(qr{^http://example\.com/$}, 'http://mysite.com'); 
    $t->flush;    # or $link->print, outputs the modified (or not) link 
    }