2

我正在尝试为目录中的每个 xml 文件打印包含字符串“kcat”的所有 HTML 表,但我遇到了一些麻烦。请注意,目录中的每个文件(名为 kcat_tables)至少有一个包含 kcat 的 HTML 表。我在 ubuntu 虚拟机上运行这个程序。这是我的代码:

#!/usr/bin/perl
use warnings;
use strict;
use File::Slurp;
use Path::Iterator::Rule;
use HTML::TableExtract;
use utf8::all;
my @papers_dir_path = qw(/home/bob/kinase/kcat_tables);

my $rule = Path::Iterator::Rule->new;
$rule->name("*.nxml");
$rule->skip_dirs(".");

my $xml;
my $it = $rule->iter(@papers_dir_path);

while ( my $file = $it->() ) {
    $xml = read_file($file);
    my $te = HTML::TableExtract->new();
    $te->parse($xml);
    foreach my $ts ( $te->tables ) {
        if ( $ts =~ /kcat/i ) {
            print "Table (", join( ',', $ts->coords ), "):\n";
            foreach my $row ( $ts->rows ) {
                print join( ',', @$row ), "\n";
            }
        }
    }
}

关于我应该如何解决这个问题的任何想法?提前致谢!另外,我对 PERL 语言还很陌生,所以非常感谢一个简单易懂的答案。

4

1 回答 1

0

您不能将正则表达式应用于对象,就像您在:

if ( $ts =~ /kcat/i ) {

我建议以“树”模式解析表格。为此,您必须安装两个额外的 perl 模块:HTML::TreeBuilder 和 HTML::ElementTable。像这样启用它:

use HTML::TableExtract 'tree';

这是固定的while循环:

while ( my $file = $it->() ) {
  $xml = read_file($file);
  my $te = HTML::TableExtract->new();
  $te->parse($xml);
  foreach my $ts ( $te->tables ) {
    my $tree = $ts->tree or die $!;
    if ( $tree->as_text =~ /kcat/i ) {
      print "Table (", join( ',', $ts->coords ), "):\n";
      # update 18.2.2015: pretty print the table
      foreach my $row ($ts->rows) {
        print join ' | ', map {sprintf "%22s", $_->as_text} @{$row};
        print "\n";
        # which is the same as
        # foreach my $cell (@${$row}) { do something with $cell->as_text }
      }
    }
  }
}

$tree 是一个 HTML::ElementTable 对象。上面的代码适用于您的示例。

于 2015-02-16T16:38:57.750 回答