代码之家  ›  专栏  ›  技术社区  ›  dusker

用perl-regex解析XML文件

  •  1
  • dusker  · 技术社区  · 16 年前

    我只是一个perl行乞者,非常迫切地需要准备一个小脚本,从xml文件中提取最重要的3个内容,并将它们放入一个新的文件中。 下面是一个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>
    

    谢谢你的帮助 当做

    2 回复  |  直到 16 年前
        1
  •  12
  •   Community Mohan Dere    9 年前

    Never ever use Regex to handle markup languages.

    此答案的原始版本(见下文)已使用 XML::XPath . 格兰特·麦克莱恩在评论中说:

    XML::XPath 是一个旧的未维护的模块。 XML::LibXML

    所以我做了一个新版本 XML::LibXML (谢谢,格兰特):

    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";
    }
    

    对我来说这个指纹:

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


    原版答案,基于 包裹:

    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";
    }
    

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

        2
  •  0
  •   Snake Plissken    16 年前

    在这里:

     open my $input, "<", "file.xml" or die $!;
     open my $output, ">", "truncated-file.xml" or die $!;
     my $n_articles = 0;
     while (<$input>) {
          print $output $_;
          if (m:</article>:) {
               $n_articles++;
               if ($n_articles >= 3) {
                    last;
               }
          }
     }         
     close $input or die $!;
     close $output or die $!;