1

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) = @_;

}

タグを分割するにはどうすればよいですか?...

4

2 に答える 2

1

方法はおそらくいくつかあります。次のコードでは、 を使用して、すべてのテキスト ノードの周り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;
}

ところで、実行可能なコードを投稿してください。サンプル コードに重要な部分 (tgtwig_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;
}
于 2013-01-04T13:45:33.307 に答える
0

完全な XML データの性質に大きく依存します。たとえば、ネストされた<p>要素が予想される場合、ソリューションはより複雑になり、動作をより適切に定義する必要があります。

ただし、このプログラムは必要なことを実行しているようで、サンプルデータで動作します。独自のコードと同様に、splitサブルーチンは検出されたすべての<p>要素を処理します。含まれているのがテキストだけの場合、要素はそのまま残ります。それ以外の場合、子は切り離され、 array に置換ノードのリストを作成するために使用されます@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-05T15:30:59.537 に答える