2011-10-11 128 views
0

所以問題在這裏。我正試圖解析來自GenBank的XML文件信息。該文件包含多個DNA序列的信息。我已經完成了genbacnk(TINY xml和INSD xml)中的其他兩種xml格式,但純xml讓我很頭疼。這是我的程序應該如何工作。下載一個xml格式的文件,其中包含來自GenBank的X個序列信息。運行我的perl腳本,它可以逐行搜索該xml文件,並以fasta格式將我想要的信息打印到新文件中。這是:>序列名稱和信息\ n序列\ n>序列名稱......並且直到您擁有來自xml文件的所有序列。我的問題是,在純xml中,序列本身出現在序列基因或基因座的標識符之前。序列的基因或基因座應與「>」一致。下面是我從打開該文件,並通過它分析的點有代碼:按行解析一個XML文件

open(New_File, "+>$PWD_file/$new_file") or die "\n\nCouldn't create file. Check permissions on location.\n\n"; 

    while (my $lines = <INSD>) { 
     foreach ($lines) { 
      if (m/<INSDSeq_locus>.*<\/INSDSeq_locus>/) { 
       $lines =~ s/<INSDSeq_locus>//g and $lines =~ s/<\/INSDSeq_locus>//g and $lines =~ s/[a-z, |]//g; #this last bit may cause a bug of removing the letters in the genbank accession number 
       $lines =~ s/ //g; 
       chomp($lines); 
       print New_File ">$lines\_"; 
      } elsif (m/<INSDSeq_organism>.*<\/INSDSeq_organism>/) { 
       $lines =~ s/<INSDSeq_organism>//g and $lines =~ s/<\/INSDSeq_organism>//g; 
       $lines =~ s/(\.|\?|\-|)/_/g; 
       $lines =~ s/_{2,}/_/g; 
       $lines =~ s/_{1,}$//; 
       $lines =~ s/^>*_{1,}//; 
       $lines =~ s/\s{2}//g; 
       chomp($lines); 
       print New_File "$lines\n"; 
      } elsif (m/<INSDSeq_sequence>.*<\/INSDSeq_sequence>/) { 
       $lines =~ s/<INSDSeq_sequence>//g and $lines =~ s/<\/INSDSeq_sequence>//g; 
       $lines =~ s/ //g; 
       chomp($lines); 
       print New_File "$lines\n"; 
      } 
     } 
    } 
    close INSD; 
    close New_File; 
} 

有兩個地方找到基因/基因信息。該信息位於這兩個標記之間:LOCUS_NAME或GENE_NAME。會有一個,或另一個。如果有人有信息,其他人將是空的。無論哪種情況,都需要添加到> .......行的末尾。

感謝,

AlphaA

PS - 我試圖打印信息,以「文件」做開放「$ NA」,「>」序列到,然後與移動上程序,找到基因信息,將其打印到>行,然後讀取$ NA文件並將其打印到行後面的行中。我希望這很清楚。

+12

是否有你選擇不使用XML解析庫的原因? –

+0

也許輸入,電流輸出和實際輸出的例子會很好。 – DavidEG

+0

@DavidEG:那麼,OP指定了GenBank,所以http://www.ncbi.nlm.nih.gov/genbank/和ftp://ftp.ncbi.nih.gov/genbank/ – derobert

回答

3

在我看來,您應該使用XSLTXPath導航到您需要的數據。

正如@布萊恩建議,使用已建立的XML解析技術和庫更容易。

甚至有一個Perl library for XSLT

4

使用XML解析器。我不是生物學家,我不確定你想要的最終格式,但它應該很簡單,以此爲出發點。 $_[1]在匿名子文件中包含一個哈希引用,從上面我可以告訴的,我認爲你想要解析所需標記的父標記時保存的所有內容。它應該很容易打印出的$元素_ [1],你希望它是格式:

use strict; 
use warnings; 

use XML::Rules; 
use Data::Dumper; 

my @rules = (
    _default => '', 
    'INSDSeq_locus,INSDSeq_organism,INSDSeq_sequence' => 'content', 
    INSDSeq => sub { delete $_[1]{_content}; print Dumper $_[1]; return }, 
); 

my $p = XML::Rules->new(rules => \@rules); 
$p->parsefile('sequence.gbc.xml'); 

而這僅僅是使打印你想要的標籤很容易。或者,如果你想一些其他的標籤,我真的會做的就是這個(你並不真正需要的@tags變量在所有如果你只是用元素打印元件):

my @tags = qw(
    INSDSeq_locus 
    INSDSeq_organism 
    INSDSeq_sequence 
); 

my @rules = (
    _default => 'content', 
    # Elements are, e.g. $_[1]{INSDSeq_locus} 
    INSDSeq => sub { print "$_: $_[1]{$_}\n" for @tags; return; }, 
); 

有:

my $p = XML::Rules->new(rules => \@rules, stripspaces => 4); 
+0

不需要'@ tags'數組和地圖。您可以指定一個字符串幾個標籤名稱字面,並用逗號分隔它們: 我@rules =( 「INSDSeq_locus,INSDSeq_organism,INSDSeq_sequence」 =>「內容」, ... – Jenda

+0

@Jenda - 注意(和我應該是已知的)並更新。 – runrig