私はこのようなXMLドキュメントを持っています:
<article>
<author>Smith</author>
<date>2011-10-10</date>
<description>Article about <b>frobnitz</b>, crulps and furtikurty's. Mainly frobnitz</description>
</article>
これをPerlで解析してから、いくつかの単語やフレーズの周りに新しいタグを追加する必要があります(たとえば、定義にリンクするため)。ターゲット単語の最初のインスタンスのみにタグを付け、特定のタグに含まれるものだけに検索を絞り込みます(たとえば、descriptionタグのみ)。
XML :: Twigで解析し、descriptionタグに「twig_handler」を設定できます。しかし、$ node-> textを呼び出すと、間にあるタグが削除されたテキストが表示されます。本当に私がやりたいのは、既存のタグが保持され、壊れないように、(非常に小さい)ツリーをトラバースすることです。したがって、最終的なXML出力は次のようになります。
<article>
<author>Smith</author>
<date>2011-10-10</date>
<description>Article about <b><a href="dictionary.html#frobnitz">frobnitz</a></b>, <a href="dictionary.html#crulps">crulps</a> and <a href="dictionary.html#furtikurty">furtikurty</a>'s. Mainly frobnitz</description>
</article>
ターゲット環境でXML::LibXMLも使用できますが、そこから開始する方法がわかりません...
これが私のこれまでの最小限のテストケースです。助けに感謝します!
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
my %dictionary = (
frobnitz => 'dictionary.html#frobnitz',
crulps => 'dictionary.html#crulps',
furtykurty => 'dictionary.html#furtykurty',
);
sub markup_plain_text {
my ( $text ) = @_;
foreach my $k ( keys %dictionary ) {
$text =~ s/(^|\W)($k)(\W|$)}/$1<a href="$dictionary{$k}">$2<\/a>$3/si;
}
return $text;
}
sub convert {
my( $t, $node ) = @_;
warn "convert: TEXT=[" . $node->text . "]\n";
$node->set_text( markup_plain_text($node->text) );
return 1;
}
sub markup {
my ( $text ) = @_;
my $t = XML::Twig->new(
twig_handlers => { description => \&convert },
pretty_print => 'indented',
);
$t->parse( $text );
return $t->flush;
}
my $orig = <<END_XML;
<article>
<author>Smith</author>
<date>2011-10-10</date>
<description>Article about <b>frobnitz</b>, crulps and furtikurty's. Mainly frobnitz's</description>
</article>
END_XML
;
markup($orig);