2012-04-25 117 views
4

我剛開始使用Perl 1周前,我是一個編程newbee。請幫助,因爲我的公司項目依賴於此。Perl:將編輯字段保存到同一個XML文件中

現狀:

我想開一個XML文件,在這個例子中是Library.xml和編輯使用一個特定的「ISBN」號的XML文檔。找到ISBN號碼後,我想要更改與「ISBN」號碼匹配的特定書籍的頁數。

問題:

現在

,我能做到上面,但我需要保存更新XML名稱相同的「library.xml」,也保持了原始XML文檔的XML結構。這是我難過的地方。我曾嘗試使用XML :: DUMPER和XML :: TWIG,可能還有其他人失敗了。

原始XML文檔:

的library.XML看起來是這樣的:

<library> 
    <book> 
    <title>Perl Best Practices</title> 
    <author>Damian Conway</author> 
    <isbn>0596001738</isbn> 
    <pages>542</pages> 
    <image src="http://www.oreilly.com/catalog/covers/perlbp.s.gif" 
      width="145" height="190" /> 
    </book> 
    <book> 
    <title>Perl Cookbook, Second Edition</title> 
    <author>Tom Christiansen</author> 
    <author>Nathan Torkington</author> 
    <isbn>0596003137</isbn> 
    <pages>964</pages> 
    <image src="http://www.oreilly.com/catalog/covers/perlckbk2.s.gif" 
      width="145" height="190" /> 
    </book> 
    <book> 
    <title>Guitar for Dummies</title> 
    <author>Mark Phillips</author> 
    <author>John Chappell</author> 
    <isbn>076455106X</isbn> 
    <pages>392</pages> 
    <image src="http://media.wiley.com/product_data/coverImage/6X/07645510/076455106X.jpg" 
     width="100" height="125" /> 
    </book> 
</library> 

驗證碼:

以下是我試圖操縱的代碼,但沒有成功。

#!/usr/bin/perl 

use strict; 
use warnings; 
#use XML::Simple qw(:strict); 

use XML::LibXML; 
use XML::Dumper; 

my $dump = new XML::Dumper; 

my $perl = ' '; 
my $xml = $dump->pl2xml($perl); 

my $filename = 'library.xml'; 

my $isbn = '0596001738'; 

my $parser = XML::LibXML->new(); 
my $doc = $parser->parse_file($filename); 

my $query = "//book[isbn = '$isbn']/pages/text()"; 

my($node) = $doc->findnodes($query); 
$node->setData('99999'); 

$perl = $doc->toString; 

$xml = $dump->pl2xml($perl, "library.xml"); 

print $doc->toString; 

輸出:

下面是我的輸出。輸出不像原始的XML文檔。

<perldata> 
<scalar>&lt;xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;&gt; 
&lt;library&gt; 
    &lt;book&gt; 
    &lt;title&gt;Perl Best Practices&lt;/title&gt; 
    &lt;author&gt;Damian Conway&lt;/author&gt; 
    &lt;isbn&gt;0596001738&lt;/isbn&gt; 
    &lt;pages&gt;99999&lt;/pages&gt; 
    &lt;image src=&quot;http://www.oreilly.com/catalog/covers/perlbp.s.gif&quot; width=&quot;145&quot; height=&quot;190&quot;/&gt; 
    &lt;/book&gt; 
    &lt;book&gt; 
    &lt;title&gt;Perl Cookbook, Second Edition&lt;/title&gt; 
    &lt;author&gt;Tom Christiansen&lt;/author&gt; 
    &lt;author&gt;Nathan Torkington&lt;/author&gt; 
    &lt;isbn&gt;0596003137&lt;/isbn&gt; 
    &lt;pages&gt;964&lt;/pages&gt; 
    &lt;image src=&quot;http://www.oreilly.com/catalog/covers/perlckbk2.s.gif&quot; width=&quot;145&quot; height=&quot;190&quot;/&gt; 
    &lt;/book&gt; 
    &lt;book&gt; 
    &lt;title&gt;Guitar for Dummies&lt;/title&gt; 
    &lt;author&gt;Mark Phillips&lt;/author&gt; 
    &lt;author&gt;John Chappell&lt;/author&gt; 
    &lt;isbn&gt;076455106X&lt;/isbn&gt; 
    &lt;pages&gt;392&lt;/pages&gt; 
    &lt;image src=&quot;http://media.wiley.com/product_data/coverImage/6X/07645510/076455106X.jpg&quot; width=&quot;100&quot; height=&quot;125&quot;/&gt; 
    &lt;/book&gt; 
&lt;/library&gt; 
    </scalar> 
</perldata> 
+0

[這後應該幫你](http://stackoverflow.com/questions/10239920/using-perl-xmlsax-to-modify-xml-documents/10241803#10241803) – tuxuday 2012-04-25 07:59:57

+0

我很好奇你在哪裏工作, d有一本Perl書籍列表。 :) – 2012-04-25 14:52:22

回答

8

你混合XML的模塊沒有很好的理由 - 在編程的第一步是瞭解你在做什麼,你不能只是拋出代碼放在一起,並期待以某種方式做你的意思。

從你的程序中刪除18行之後,代碼看起來像這樣和正常工作:

#!/usr/bin/perl 
use strict; 
use warnings; 
use XML::LibXML; 

my $filename = 'library.xml'; 
my $isbn = '0596001738'; 

my $parser = XML::LibXML->new(); 
my $doc = $parser->parse_file($filename); 
my $query = "//book[isbn = '$isbn']/pages/text()"; 
my($node) = $doc->findnodes($query); 
$node->setData('99999'); 
print $doc->toString; 

缺少的是寫更改的文件放回文件的唯一的事:

$doc->toFile('library.xml'); 
+0

感謝您的建議。管理完成任務成功。將採取建議學習perl。再次感謝。 – 2012-04-25 18:21:59

7

XML::Twig解決方案:

#!/usr/bin/perl 

use strict; 
use warnings; 

use XML::Twig; 

# That's probably not how you get the data 
my %isbn_to_pages= ('0596001738' => 999, 
        '076455106X' => 123, 
        ); 

XML::Twig->new(twig_handlers => { book => \&book }, 
       keep_spaces => 1, 
      ) 
      # the second argument creates a backup file book_data.xml.bak 
      ->parsefile_inplace('book_data.xml', '.bak'); 


sub book 
    { my($t, $book)= @_; 
    my $isbn= $book->field('isbn'); 
    if(my $pages= $isbn_to_pages{$isbn}) 
     { $_->first_child('pages')->set_text($pages); } 
    $t->flush; 
    } 
+0

該解決方案能夠保存文件。請問,上面的命令中的哪一個實際上打開了原始的XML?感謝您的幫助... – 2012-04-25 09:01:05

+0

來自文檔:'parsefile_inplace'解析並更新文件「到位」。它通過創建一個臨時文件,選擇它作爲print()語句(和方法)的缺省值,然後解析輸入文件。如果解析成功,則移動臨時文件 以替換輸入文件。 – mirod 2012-04-25 09:42:24