Синтаксический анализ XML-файла с помощью perl - regex - PullRequest
1 голос
/ 03 июня 2010

Я только начинающий в 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>

Я хотел бы получить первые 3 элемента вместе со всеми тегами между ними и поместить их в другой файл.Спасибо за всю помощь заранее с уважением Питер

Ответы [ 2 ]

12 голосов
/ 03 июня 2010

Никогда не используйте Regex для обработки языков разметки.

Оригинальная версия этого ответа (см. Ниже) использовала XML::XPath. Грант Маклин сказал в комментариях:

XML::XPath - старый и не обслуживаемый модуль. XML::LibXML - это современный поддерживаемый модуль с почти идентичным API, и он также быстрее.

поэтому я сделал новую версию, которая использует 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

Ссылки на соответствующую документацию:


Оригинальная версия ответа, основанная на пакете 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";
}

который печатает это для меня:

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

Посмотрите документы, чтобы узнать, что вы можете с ними сделать.

0 голосов
/ 03 июня 2010

Здесь:

 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 $!;

Вам действительно не нужен анализатор XML для такой простой работы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...