我是xml-twig的新手,如何拆分父标签?
文件:
<xml>
<p class="indent">text text incluce <div>text</div> ateas</p>
<p class="text">text text incluce <div>text</div> ateas</p>
</xml>我需要如下输出:
<xml>
<p class="indent">text text incluce</p>
<div>text</div>
<p class="indent">ateas</p>
<p class="text">text text incluce</p>
<div>text</div>
<p class="text">ateas</p>
</xml>如何拆分标签?
use strict;
use XML::Twig;
open(my $output , '>', "split.xml") || die "can't open the Output $!\n";
my $xml_twig_content = XML::Twig->new(
'p' => \&split, )
$xml_twig_content->parsefile("sample.xml");
$xml_twig_content->print($output);
sub split{
my ($xml_twig_content, $p) = @_;
}如何拆分标签?...
发布于 2013-01-05 23:31:00
这在很大程度上取决于完整XML数据的性质。例如,如果您期望嵌套的<p>元素,那么解决方案就复杂得多,并且需要更好地定义行为。
然而,这个程序似乎做了您需要做的事情,并且处理您的样本数据。与您自己的代码一样,split子例程处理遇到的每个<p>元素。如果一个元素只包含文本,则该元素保持不变,否则子元素将被分离并用于在数组@split中创建替换节点列表。通过创建父<p>元素的克隆并将文本粘贴为其内容来转换此列表中的文本节点。修改所有文本节点后,对replace_with的调用将用新的元素列表替换原始的<p>元素。
注意,print_to_file方法避免了单独打开输出文件的需要。
use strict;
use warnings;
use XML::Twig;
my $twig = XML::Twig->new(
twig_handlers => { p => \&split },
);
$twig ->parsefile('sample.xml');
$twig->print_to_file('split.xml', pretty_print => 'indented');
sub split{
my ($twig, $p) = @_;
return if $p->contains_only_text;
my @split = $p->cut_children;
for my $child (grep $_->is_pcdata, @split) {
my $text = $child;
$child = $p->copy;
$text->paste(last_child => $child);
}
$p->replace_with(@split);
}输出
<xml>
<p class="indent">text text incluce </p>
<div>text</div>
<p class="indent"> ateas</p>
<p class="text">text text incluce </p>
<div>text</div>
<p class="text"> ateas</p>
</xml>发布于 2013-01-04 21:45:33
可能有几种方法可以做到这一点。下面的代码使用wrap_in,它在所有文本节点周围添加一个新的<p>,然后使用erase删除原始<p>。atts用于将原始<p>的属性复制到新的属性中。
#!/usr/bin/perl
use warnings;
use strict;
use XML::Twig;
open(my $output , '>', "split.xml") || die "can't open the Output $!\n";
my $xml = XML::Twig->new( twig_handlers => { p => \&split_tag } );
$xml->parsefile("1.xml");
$xml->print($output);
sub split_tag {
my ($twig, $p) = @_;
$_->wrap_in('p', $p->atts) for $p->children('#TEXT');
$p->erase;
}顺便说一句,请发布一个可运行的代码。您的示例代码遗漏了重要的部分(t.g.twig_handlers或分号)。
sub split_tag {
my ($twig, $p) = @_;
CHILD:
for my $ch ($p->children(sub {'div' ne shift->name})) {
my $wrap = $ch->wrap_in('p', $p->atts);
my $prev = $wrap->prev_sibling or next CHILD;
$prev->merge($wrap) if 'p' eq $prev->name;
}
$p->erase;
}https://stackoverflow.com/questions/14156289
复制相似问题