Perl XML Convert Solution - PullRequest
       32

Perl XML Convert Solution

0 голосов
/ 06 января 2011

Я новичок в модулях Perl и CPAN

Я хочу конвертировать XML-файл, включающий:

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

К

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

У вас есть умные решения? с модулем CPAN

Ответы [ 3 ]

3 голосов
/ 06 января 2011

Ниже приведено простое решение с использованием XML :: Twig.По сравнению с опцией XML :: Simple он работает независимо от того, где элементы Link находятся в XML, и будет учитывать исходное форматирование файла.Это также будет работать, если XML содержит смешанное содержимое.

Если вам нужно изменить файл на месте, вы можете использовать parsefile_inplace вместо parsefile, и я подозреваю, что регулярное выражение в subs_textможет потребоваться улучшение в реальной жизни, но этот код должен стать хорошей отправной точкой.

#!/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
  }           
3 голосов
/ 06 января 2011
  • см. XML :: Twig - Perl-модуль для обработки больших XML-документов в режиме дерева.
  • или XML :: Simple - Простой API для поддержки XML (файлы конфигурации esp)

как

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);

выход:

<?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 голосов
/ 06 января 2011

Если все, что вам нужно, это изменить конкретное значение, вам не нужно ничего особенного, вы можете просто использовать regexp:
из командной строки:

perl -pi -e 's@http://example.com/@http://mysite.com/@g' file.xml

edit : добавление полной версии кода:

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")
...