我是XML::Twig
的新手。
我需要将子标记移动到子标记。
我该怎么做?
当我将notes
标记与父级标记与子级移动到部分之前时。
我的XML看起来像这样:
<book>
<sec>
<p>The indicated something</p>
<p>The something</p>
</sec>
<sec>
<notes>note</notes>
<p>text</p>
</sec>
<sec>
<p>The indicated</p>
<p>The something</p>
</sec>
<sec>
<notes>note</notes>
<p>text1</p>
</sec>
</book>
我试过了:
use XML::Twig;
open(my $output, ">output.xml") || die "can't open the output.xml$!\n";
my $story_file = XML::Twig->new(
keep_encoding => 1,
twig_handlers => { 'book' => \&book, },
pretty_print => 'indented',
);
$story_file->parse("sample.xml");
$story_file->print($output);
$story_file->purge;
sub book {
my ($stroy_file, $book) = @_;
my @sub_elmt = $book->children;
Get_children(\@sub_elmt) if ($#sub_elmt >= 0);
}
sub Get_children {
my ($ref) = @_;
foreach my $tagg (@$ref) {
my @children = $tagg->children;
my $tagName = $tagg->name;
if ($tagName =~ /^sec$/) {
my $f = $tagg->first_child;
if ($f->name =~ /^notes$/) {
$tagg->move('last_child', $tagg);
}
}
Get_children(\@children) if ($#children >= 0);
}
}
它不起作用,我该怎么做?
我需要这样的输出:
<book>
<sec>
<p>The indicated something</p>
<p>The something</p>
<sec>
<notes>note</notes>
<p>text</p>
</sec>
</sec>
<sec>
<p>The indicated</p>
<p>The something</p>
<sec>
<notes>note</notes>
<p>text1</p>
</sec>
</sec>
</book>
我是怎么做到的?
答案 0 :(得分:1)
XML::Twig
对于使用twig_handlers
逐个处理非常大的XML文档非常有用,但是 没有像这样使用它。它将构建一个完整的XML文档树,让您可以操作该树并将其打印出来,就像大多数其他XML模块一样。
此程序从sample.xml
读取整个文档,然后搜索notes
元素内的所有sec
元素。使用sec
找到包含parent
元素的内容,并使用sec
找到之前的prev_sibling
元素(要插入此元素)。然后move
用于将sec
元素重新定位为前一个sec
的最后一个子元素。
use strict;
use warnings;
use XML::Twig;
my $twig = XML::Twig->new;
$twig->parsefile('sample.xml');
for my $notes ( $twig->findnodes('//sec/notes') ) {
my $sec = $notes->parent;
my $prev_sec = $sec->prev_sibling('sec');
$sec->move(last_child => $prev_sec);
}
$twig->print_to_file('output.xml', pretty_print => 'indented');
<强>输出强>
<book>
<sec>
<p>The indicated something</p>
<p>The something</p>
<sec>
<notes>note</notes>
<p>text</p>
</sec>
</sec>
<sec>
<p>The indicated</p>
<p>The something</p>
<sec>
<notes>note</notes>
<p>text1</p>
</sec>
</sec>
</book>
答案 1 :(得分:0)
您的XML和Perl脚本中都存在一些拼写错误。 NB。我修改了&amp;整理了您的XML示例(请参阅 notes 标记)。
您的主要问题是$tagg->move
正在转移到$tagg
(即本身!),因此无效:(
下面是我的简化版本,可以满足您的需求(即,当它看到book/sec
标记带有第一个孩子notes
时,它会将此sec
移到上一个{{1}的末尾}}并演示sec
的工作原理。
->move