2012-04-25 78 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