Solução de convertido Perl XML
-
26-09-2019 - |
Pergunta
Eu sou iniciante para módulos Perl e CPAN
Eu quero converter um arquivo xml incluir:
<Item><Link>http://example.com/</Link></Item>....
Para
<Item><Link>http://mysite.com/</Link></Item>....
Você tem soluções inteligentes? com Módulo CPAN
Solução
- Vejo Xml :: twig - Um módulo Perl para processar grandes documentos XML no modo árvore.
- ou Xml :: Simple - API fácil de manter XML (arquivos de configuração ESP)
Curti,
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);
resultado:
<?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>
Outras dicas
Uma solução simples usando XML :: Twig está abaixo. Comparado com a opção xml :: simples, não importa onde Link
Os elementos estão no XML e respeitarão a formatação original do arquivo. Também funcionará se o XML contiver conteúdo misto.
Se você precisar alterar o arquivo no lugar, você pode usar parsefile_inplace
ao invés de parsefile
, e eu suspeito que a expressão regular em subs_text
Pode ser necessário melhorar na vida real, mas esse código deve ser um bom ponto de partida.
#!/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
}
Se tudo o que você precisa é alterar um valor específico, você realmente não precisa de nada de especial, basta usar o regexp:
da linha de comando:
perl -pi -e 's@http://example.com/@http://mysite.com/@g' file.xml
editar : Adicionando versão completa do código:
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>) {
s@http://example.com/@http://mysite.com/@g;
print OUT $_;
}
close(IN);
close(OUT);
rename("$file.tmp", "$file")