使用perl - regex解析XML文件

dus*_*ker 1 regex perl

我只是perl中的一个初学者,并且非常迫切需要准备一个小脚本,它从xml文件中获取前三项内容并将它们放入一个新脚本中.这是一个xml文件的示例:

    <article>
  {lot of other stuff here}
</article>
<article>
  {lot of other stuff here}
</article>
<article>
  {lot of other stuff here}
</article>
<article>
  {lot of other stuff here}
</article>
Run Code Online (Sandbox Code Playgroud)

我想做的是获得前3个项目以及其间的所有标签并将其放入另一个文件中.感谢所有的帮助提前问候彼得

Tom*_*lak 12

永远不要使用Regex来处理标记语言.

使用了这个答案的原始版本(见下文)XML::XPath.Grant McLean在评论中说:

XML::XPath是一个古老而无需维护的模块.XML::LibXML是一个现代化的维护模块,具有几乎相同的API,而且速度也更快.

所以我创建了一个使用的新版本XML::LibXML(谢谢,Grant):

use warnings;
use strict;
use XML::LibXML;

my $doc   = XML::LibXML->load_xml(location => 'articles.xml');
my $xp    = XML::LibXML::XPathContext->new($doc->documentElement);
my $xpath = '/articles/article[position() < 4]';

foreach my $article ( $xp->findnodes($xpath) ) {
  # now do something with $article
  print $article.": ".$article->getName."\n";
}
Run Code Online (Sandbox Code Playgroud)

对我来说这打印:

XML::LibXML::Element=SCALAR(0x346ef90): article
XML::LibXML::Element=SCALAR(0x346ef30): article
XML::LibXML::Element=SCALAR(0x346efa8): article

相关文件的链接:


原始版本的答案,基于XML::XPath包:

use warnings;
use strict;
use XML::XPath;

my $xp    = XML::XPath->new(filename => 'articles.xml');
my $xpath = '/articles/article[position() < 4]';

foreach my $article ( $xp->findnodes($xpath)->get_nodelist ) {
  # now do something with $article
  print $article.": ".$article->getName ."\n";
}
Run Code Online (Sandbox Code Playgroud)

这打印给我:

XML::XPath::Node::Element=REF(0x38067b8): article
XML::XPath::Node::Element=REF(0x38097e8): article
XML::XPath::Node::Element=REF(0x3809ae8): article

查看文档以了解您可以使用它们做什么.

  • @Snake Plissken:不,不是.对于那种工作,正则表达式永远不是*正确的工具,无论它看起来多么"轻松".XPath +编程语言X(在本例中为Perl)是,或XSLT.正则表达式不是. (5认同)
  • @Snake Plissken:我不是很傻.我只是想避免在何时使用正确的解析器时很聪明.Perl内置了一个很好的XML解析器,绝对没有理由不使用它.(这不是"哦,该死,我必须使用解析器,因为这对于正则表达式来说太复杂了",它是"哦该死的,我不能使用解析器,因为我使用的语言不提供".而后者几乎是从来没有.) (2认同)