我有一个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,然后我可以进一步操作它们的内容。
发布于 2019-01-29 02:52:47
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"。
发布于 2019-01-29 02:45:54
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 (据我所知)不太适合查找动态标记名,所以你必须自己做这件事;如果它是动态属性,那就很容易了。
https://stackoverflow.com/questions/54406280
复制相似问题