我有一个xml结构,我希望编写一个perl脚本来读取以特定字符串开头的所有标签的内容。
示例:
<tag-0>
<tag-1>This is<tag-2>some example</tag2>text</tag-1>
<tag-3>This is some <ice-8> more </ice-8>text</tag-3>
<tag-4>This
<tag-5>is
<tag-6>even more</tag-6>
</tag-5>
<tag-7> text</tag-7>
</tag-4>
</tag-0>
该脚本的目的是查找以<tag-[num]>
开头的所有包含嵌套<tag-[num]>
的节点。我对perl不熟悉,那么我将如何读取“动态”标签的内容,并检查更多的动态嵌套标签?
在上面的示例中,我想获取tag-0,tag-1,tag-4和tag-5,然后可以进一步操纵它们的内容。
答案 0 :(得分:2)
XML::LibXML
是我最常用的XML模块-还有很多其他模块,但是这个模块几乎可以满足我的所有需求,但有时会比其他模块更加冗长。下面显示了四个所需的节点:
use warnings;
use strict;
use XML::LibXML;
my $dom = XML::LibXML->load_xml(string => <<'EOT');
<tag-0>
<tag-1>This is<tag-2>some example</tag-2>text</tag-1>
<tag-3>This is some <ice-8> more </ice-8>text</tag-3>
<tag-4>This
<tag-5>is
<tag-6>even more</tag-6>
</tag-5>
<tag-7> text</tag-7>
</tag-4>
</tag-0>
EOT
my $expr = "*[substring(name(), 1, 4) = 'tag-']";
for my $node ( $dom->findnodes("//$expr") ) {
my @children = $node->findnodes("./$expr");
if (@children) {
print $node->nodeName,"\n";
}
}
请注意,您的问题描述有点不清楚:“包含嵌套的<tag-[num]>
” 意味着仅考虑直接后代,还是应该返回<tag-0>A<x>B<tag-1>C</tag-1>D</x>E</tag-0>
tag-0
?
如果是这样,则可以将第二个findnodes
表达式更改为".//$expr"
。
答案 1 :(得分:1)
使用Mojo::DOM:
use strict;
use warnings;
use Mojo::DOM;
my $dom = Mojo::DOM->new->xml(1)->parse($xml);
my @tags_with_subtags = $dom->find('*')->grep(sub {
$_->tag =~ m/\Atag-[0-9]+\z/ and $_->find('*')->grep(sub {
$_->tag =~ m/\Atag-[0-9]+\z/
})->size
})->each;
每个结果都是一个Mojo :: DOM对象,您可以进一步搜索或操作。不幸的是,CSS(据我所知)并不适合查找动态标签名称,因此您必须自己做一点;如果它是动态属性,那将非常容易。