我刚开始使用Perl 1周前,我是一个编程newbee。请帮助,因为我的公司项目依赖于此。
情况:
我想打开一个XML文件,在这个例子中是Library.xml,并使用特定的“ISBN”编号编辑XML文档。找到ISBN号后,我想用匹配的“ISBN”号码更改特定书籍的页数。
问题:
现在,我可以执行上述操作,但是,我需要使用相同名称“library.xml”保存更新的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><xml version="1.0" encoding="UTF-8">
<library>
<book>
<title>Perl Best Practices</title>
<author>Damian Conway</author>
<isbn>0596001738</isbn>
<pages>99999</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>
</scalar>
</perldata>
答案 0 :(得分: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');
答案 1 :(得分: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;
}