- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
我有一个这样的 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 中解析它,然后在一些单词或短语周围添加新标签(例如链接到定义)。我只想标记目标词的第一个实例,并将搜索范围缩小到给定标签中的内容(例如,仅描述标签)。
我可以用 XML::Twig 解析并为描述标签设置一个“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);
最佳答案
这是一个有点棘手的问题,但 XML::Twig 是为这种处理而设计的(我经常使用它)。所以有一个名为 mark
的特定方法,它采用正则表达式并标记匹配项。
在这种情况下,正则表达式可能会非常大。我使用 Regexp::Assempble 来构建它,因此它得到了优化。然后另一个问题是 mark
不允许你使用匹配的文本来设置属性(我可能会在模块的下一个版本中处理这个,那会很有用),所以我必须先标记,然后返回并在第二遍中设置 href
属性(在任何情况下都需要第二遍来“取消链接”已经链接的单词)。
最后一句话:我差点放弃编写解决方案,因为您的示例数据有一些拼写错误。没有什么比正确编写代码更糟糕的了,只是看到测试仍然失败,因为您在代码中使用了“字典”,在数据中使用了“定义”,或者在应该全部使用的地方使用了“furtykurtle”、“furtikurty”和“furtijurty”是同一个词。因此,请在发布之前确保您的数据正确无误。值得庆幸的是,我正在编写代码作为测试。
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
use Regexp::Assemble;
use Test::More tests => 1;
use autodie qw(open);
my %dictionary = (
frobnitz => 'definitions.html#frobnitz',
crulps => 'definitions.html#crulps',
furtikurty => 'definitions.html#furtikurty',
);
my $match_defs= Regexp::Assemble->new()
->add( keys %dictionary)
->anchor_word
->as_string;
# I am not familiar enough with Regexp::Assemble to know a cleaner
# way to get get the capturing braces in the regexp
$match_defs= qr/($match_defs)/;
my $in = data_para();
my $expected = data_para();
my $out;
open( my $out_fh, '>', \$out);
XML::Twig->new( twig_roots => { 'description' => sub { tag_defs( @_, $out_fh, $match_defs, \%dictionary); } },
twig_print_outside_roots => $out_fh,
)
->parse( $in);
is( $out, $expected, 'base test');
exit;
sub tag_defs
{ my( $t, $description, $out_fh, $match_defs, $dictionary)= @_;
my @a= $description->mark( $match_defs, 'a' );
# word => 1 when already used in this description
# this might need to have a different scope if you need to tag
# only the first time the word appears in a section or whatever
my $tagged_in_description;
foreach my $a (@a)
{ my $word= $a->text;
warn "checking a: ", $a->sprint, "\n";
if( $tagged_in_description->{$word})
{ $a->erase; } # we did not need to tag it after all
else
{ $a->set_att( href => $dictionary->{$word}); }
$tagged_in_description->{$word}++;
}
$t->flush( $out_fh); }
sub def_href
{ my( $word)= @_;
return $dictionary{word};
}
sub data_para
{ local $/="\n\n";
my $para= <DATA>;
return $para;
}
__DATA__
<article>
<author>Smith</author>
<date>2011-10-10</date>
<description>Article about <b>frobnitz</b>, crulps and furtikurty's. Mainly frobnitz</description>
</article>
<article>
<author>Smith</author>
<date>2011-10-10</date>
<description>Article about <b><a href="definitions.html#frobnitz">frobnitz</a></b>, <a href="definitions.html#crulps">crulps</a> and <a href="definitions.html#furtikurty">furtikurty</a>'s. Mainly frobnitz</description>
</article>
关于xml - 如何在 Perl 中修改复杂的 XML 文档以向文本节点添加额外的标记?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5972732/
我需要将文本放在 中在一个 Div 中,在另一个 Div 中,在另一个 Div 中。所以这是它的样子: #document Change PIN
奇怪的事情发生了。 我有一个基本的 html 代码。 html,头部, body 。(因为我收到了一些反对票,这里是完整的代码) 这是我的CSS: html { backgroun
我正在尝试将 Assets 中的一组图像加载到 UICollectionview 中存在的 ImageView 中,但每当我运行应用程序时它都会显示错误。而且也没有显示图像。 我在ViewDidLoa
我需要根据带参数的 perl 脚本的输出更改一些环境变量。在 tcsh 中,我可以使用别名命令来评估 perl 脚本的输出。 tcsh: alias setsdk 'eval `/localhome/
我使用 Windows 身份验证创建了一个新的 Blazor(服务器端)应用程序,并使用 IIS Express 运行它。它将显示一条消息“Hello Domain\User!”来自右上方的以下 Ra
这是我的方法 void login(Event event);我想知道 Kotlin 中应该如何 最佳答案 在 Kotlin 中通配符运算符是 * 。它指示编译器它是未知的,但一旦知道,就不会有其他类
看下面的代码 for story in book if story.title.length < 140 - var story
我正在尝试用 C 语言学习字符串处理。我写了一个程序,它存储了一些音乐轨道,并帮助用户检查他/她想到的歌曲是否存在于存储的轨道中。这是通过要求用户输入一串字符来完成的。然后程序使用 strstr()
我正在学习 sscanf 并遇到如下格式字符串: sscanf("%[^:]:%[^*=]%*[*=]%n",a,b,&c); 我理解 %[^:] 部分意味着扫描直到遇到 ':' 并将其分配给 a。:
def char_check(x,y): if (str(x) in y or x.find(y) > -1) or (str(y) in x or y.find(x) > -1):
我有一种情况,我想将文本文件中的现有行包含到一个新 block 中。 line 1 line 2 line in block line 3 line 4 应该变成 line 1 line 2 line
我有一个新项目,我正在尝试设置 Django 调试工具栏。首先,我尝试了快速设置,它只涉及将 'debug_toolbar' 添加到我的已安装应用程序列表中。有了这个,当我转到我的根 URL 时,调试
在 Matlab 中,如果我有一个函数 f,例如签名是 f(a,b,c),我可以创建一个只有一个变量 b 的函数,它将使用固定的 a=a1 和 c=c1 调用 f: g = @(b) f(a1, b,
我不明白为什么 ForEach 中的元素之间有多余的垂直间距在 VStack 里面在 ScrollView 里面使用 GeometryReader 时渲染自定义水平分隔线。 Scrol
我想知道,是否有关于何时使用 session 和 cookie 的指南或最佳实践? 什么应该和什么不应该存储在其中?谢谢! 最佳答案 这些文档很好地了解了 session cookie 的安全问题以及
我在 scipy/numpy 中有一个 Nx3 矩阵,我想用它制作一个 3 维条形图,其中 X 轴和 Y 轴由矩阵的第一列和第二列的值、高度确定每个条形的 是矩阵中的第三列,条形的数量由 N 确定。
假设我用两种不同的方式初始化信号量 sem_init(&randomsem,0,1) sem_init(&randomsem,0,0) 现在, sem_wait(&randomsem) 在这两种情况下
我怀疑该值如何存储在“WORD”中,因为 PStr 包含实际输出。? 既然Pstr中存储的是小写到大写的字母,那么在printf中如何将其给出为“WORD”。有人可以吗?解释一下? #include
我有一个 3x3 数组: var my_array = [[0,1,2], [3,4,5], [6,7,8]]; 并想获得它的第一个 2
我意识到您可以使用如下方式轻松检查焦点: var hasFocus = true; $(window).blur(function(){ hasFocus = false; }); $(win
我是一名优秀的程序员,十分优秀!