2010-11-28 93 views
1

我正在處理一個Perl腳本,它需要根據用戶輸入填充XML文件。用戶將提供國家名稱和城市名稱。如果他/她提供:japan和e,我需要在日本標籤中填寫 - 但是作爲最後一個條目。我如何才能做到這一點?國家標籤中的城市可能很多。如何將城市添加爲相應國家/地區代碼中的最後一個標記?Perl腳本來填充XML文件

每次我需要添加一個城市時,如何才能在相關國家/地區標籤的末尾達到?

PS:我沒有使用任何內置的數據結構來存儲數據。我只是在文件中添加了啞線。

Samlple輸出XML文件:

<country name="japan-"> 
    <city>a</city> 
    <city>b</city> 
    <city>c</city> 
    <city>d</city> 
</country> 
<country name="china-"> 
    <city>aa</city> 
    <city>bb</city> 
    <city>cc</city> 
    <city>dd</city> 
</country> 

我有一個更具體的問題,Change an XML file content via Perl script

回答

4

XML::Simple是......簡單。 :) 它雖然需要一個根元素:

#!/usr/bin/env perl 

use strict; 
use warnings; 

use XML::Simple; 
use Data::Dumper; 

my $xml = join "\n", <DATA>; 
my $doc = XMLin($xml, KeepRoot => 1); 

# Get the list of cities as a list, then push "Tokyo" to it. 
push @{$doc->{countries}->{country}->{'japan-'}->{city}}, 'Tokyo'; 

print XMLout($doc, KeepRoot => 1); 

__DATA__ 
<countries> 
    <country name="japan-"> 
     <city>a</city> 
     <city>b</city> 
     <city>c</city> 
     <city>d</city> 
    </country> 
    <country name="china-"> 
     <city>aa</city> 
     <city>bb</city> 
     <city>cc</city> 
     <city>dd</city> 
    </country> 
</countries> 

輸出:

<countries> 
    <country name="china-"> 
    <city>aa</city> 
    <city>bb</city> 
    <city>cc</city> 
    <city>dd</city> 
    </country> 
    <country name="japan-"> 
    <city>a</city> 
    <city>b</city> 
    <city>c</city> 
    <city>d</city> 
    <city>Tokyo</city> 
    </country> 
</countries> 
0

我想你的意思是:如何根據用戶輸入加載XML文件並向其添加條目?

如果我理解正確的話:您使用像XML :: Simple這樣的解析器/書寫器(也有類似XML :: Twig的更好的解析器/書寫器,所以稍微探索一下)將該文件加載到哈希的Perl數據結構和數組。 (使用Data :: Dumper來檢查它在內存中的外觀。)然後,使用普通的Perl數據交互編輯該結構,並在完成後使用編寫器將其轉換回XML。

+0

對不起,我很困惑。我知道如何編寫XML內容。我的問題是關於如何將城市添加爲國家/地區代碼的最後一個條目。我是否需要遍歷所有現有的城市條目,並在達到最後一個標記時,需要在那裏添加新請求的城市。如何實現這一目標? – hari 2010-11-28 21:44:36

+0

呃,如果你用解析器讀取XML文件,你將得到一個國家的哈希值,按鍵(最好的情況下)排序,每個國家包含每個國家的城市數組。因此,您只需從國家/地區哈希中選擇正確的值,獲取其城市數組並將其推入該數組。困難在哪裏? – Mithaldu 2010-11-28 21:55:49

+0

感謝Mithaldu,我仍然在學習如何在Perl中使用XML。 – hari 2010-11-29 00:51:06

0

下面是一個使用XML::Twig溶液。我認爲它做到了你想要的。它使用的XML :: Twig最顯着的特性是使用id => name選項將name屬性作爲ID使用,因此可以直接使用$t->elt_idinsert_new_elt方法找到元素,以在樹中創建新元素。其簽名是(<position: before, after, first_child or last_child>, <tag_name>, <{attributes}>, <content>),

#!/usr/bin/perl 

use strict; 
use warnings; 

use XML::Twig; 

my $t= XML::Twig->new(id => 'name', # treat the name attribute as an ID 
         pretty_print => 'indented' 
        ) 
       ->parse(\*DATA); 

add_city($t, japan => "Kobe"); 
add_city($t, japan => "Tokyo"); 
add_city($t, china => "Beijing"); 
add_city($t, china => "Shanghai"); 
add_city($t, japan => "Kobe"); 
add_city($t, south_korea => "Seoul"); 

$t->print; 

sub add_city 
    { my($t, $country_name, $city_name)= @_; 

    my $country= $t->elt_id($country_name); 
    if(! $country) 
     { warn "creating country '$country_name'\n"; 
     $country= $t->root->insert_new_elt(last_child => country 
              => { name => $country_name } 
             ); 
     } 

    if($country->first_child(qq{city[text()="$city_name"]})) 
     { warn "city '$city_name' already found in '$country_name', skipping\n"; 
     return; 
     } 

    warn "adding '$city_name' to '$country_name', skipping\n"; 
    $country->insert_new_elt(last_child => 'city', $city_name); 
    } 


__DATA__ 
<countries> 
    <country name="japan"> 
    </country> 
    <country name="china"> 
    </country> 
</countries>