2011-01-06 155 views
0

我爲Perl和CPAN模塊初學者perl的XML轉換解決方案

我想轉換一個XML文件包括:

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

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

你有聰明的解決方案?與CPAN模塊

回答

3
  • 看到XML::Twig - 在樹方式處理巨大的XML文檔的Perl模塊。
  • 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

如果你需要的是改變一個特定的值,你並不需要特別的東西,你可以簡單地使用正則表達式:
從命令行:

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

編輯:添加完整的代碼版本:

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用於指定正則表達式的解決方案完全知道XML宗教偏執者會無情懲罰你!成爲一名開放且有用的系統管理員的訣竅是知道何時使用簡單的解決方案以及何時使用重量級的解決方案(只有少數XML粉絲會認爲簡單解決方案有時足以滿足需求)。 – 2011-01-06 13:58:13

3

使用XML的簡單解決方案::嫩枝如下。與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 
    }   
相關問題