Valid XHTML     Valid CSS2    

Séquences bioinformatiques et XML

                     gilles.hunault "at" univ-angers.fr

Table des matières cliquable

  1. Formats de séquences biologiques en bioinformatique

  2. Grammaires et vérifications

  3. Transformations simples

  4. Fichiers XML des grands centres de bioinformatique

1. Formats de séquences biologiques en bioinformatique

Dans sa version minimale, une séquence bioinformatique se réduit à un couple (identifiant, séquence codée). L'idenfiant est parfois un numéro d'accession pour une banque de données bioinformatiques comme AAA18335, BN000065, 424143 ou P14602, ou un simple mot explicite, comme HSP_27. La séquence est soit nucléotidique (ADN) soit polypeptidique (protéines). Dans le premier cas, l'alphabet correspond aux 4 lettres A, C, G et T. Dans le second cas, il se compose des 20 lettres du code IUPAC. Les séquences sont obtenues de plus en plus rapidement et de plus en plus massivement (2014) pour des couts assez faibles. Voir page exemple la page séquençage de notre collègue Emmanuel JASPARD de l'université d'Angers.

Le format dit Fasta, qui est un "vieux" format texte non XML utilise une syntaxe particulière pour stocker une séquence. En voici un exemple nucléotique (fastaxmp_adn.txt) :


     >Sangsue, ACE
     aatttaaaaatgaatttaataaatttttcatacttaaatttgctttttggtgccggtttatttagcgttttagaaagcgc
     tacaatattaaataccgaatcggatgctaaaaaatggctgacaacgtataacgatgaagccggaaaatatatttacgatg
     caactgaagcagaatggaattacaacaccaacctgactgatcacaatttaggaatttctattaaaaaatcaaatgatttg
     gctacttttacggaacaaaaggcaatcgaggccaataaaaaatttgtatggaaaaattttactgatccacttttgaaaag
     agaattttcaaaaataactgacattggtactgctagcctttcagatgaagactttcaaaagatgtcaggtttgaactctg
     atctaacaaaaatttacagcactgcaaaagtttgtaacaagcctaacgacccatctggaaaatgctatcctttagatcct
     gatttgtccgacataatctccaagtcaaacgatctcgaggaattgacctgggcatggaaaggttggagggatgcgtctgg
     caaacatatgcccgataaatatgatgaatttgttcaactgctcaacaaagctgctaagattcatggatatgaagacaacg
     gggattattggaggtcctggtacgagtcccccacgttcagaaaggattgtgaagatttgtggcaggagatcaaaccattc
     tacgaacaactgcatgcatacgtcagaaggaagctgcagaagaagtatccccaaattgcattccccaaggaggggcccat
     ccctgctcatctgctcggcaacatgtgggcccaatcgtgggagaacatagagtacttgttatgggcccaatcgtgggaga
     acatagagtacttgttaaggcccgctcctgaccttcctagcatggacatcactgaggaactcgtcaaacagaactacacg
     gcattgaaactcttccaactgtcggacacatttttcaaatccttgggtctcatccagatgcctcagccgttttgggaaaa
     gtcgatgatcgagaaaccagctgatcgggatgtgttcagaatcaaacaatgcgtttgccatgcgtcagcctgggacttct
     acaatcgcaaggatacggttgtggacatgcactggttcatgacgactcaccatgagatgggacacatcgaatactacctc
     cactacaaggaccaacccatcagtttcagatctggcgctaatccaggatttcatgaggccattgccgatattgcatcact
     gtcagtggccacacctgaatatatgcaatccgtcagcctgttgcctaatttcactgacgatccaaatggcgatttaaact
     tcttaatgaaccaagccttaacgaaggtggccttcctaccattcggttacctgatcgaccagtggagatgggacgtgttc
     tcgggagatacccctcgaccaaaatacaactccaagtggtggcacaacaggtgtaagtaccagggcatatatcctccagt
     gaaaaggtcagagcaagattttgatgccggttccaagttccatgtacccaacaacactccatacatcaggtactttgttg
     ctcacgtcatccaattccaattccatgaagccctgtgcaaggctgccaacaacagcagacctctacatagatgtaacatc
     gccaattccaaggaagctggagagaaactggctgaattgatgaaatctggatcttcaattccgtggcctaaagttctaga
     aaatcttactggatcggaaaaaatgtcagcgaaatctctcatggcctattacaaaccgttgatcgattggcctgaaaaaa
     gaaaaccaagggcagaaaattggatgggaggaaaaatgtcctcctggatcatttgaaccatgaaattatttatttgattt
     tatgtcatttcataatttttctaccacttttttaataaacttaggtgcctattgaatatgttcttgcaatttgaaaaaaa
     aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
     >AB000263
     acaagatgccattgtcccccggcctcctgctgctgctgctctccggggccacggccaccgctgccctgcc
     cctggagggtggccccaccggccgagacagcgagcatatgcaggaagcggcaggaataaggaaaagcagc
     ctcctgactttcctcgcttggtggtttgagtggacctcccaggccagtgccgggcccctcataggagagg
     aagctcgggaggtggccaggcggcaggaaggcgcacccccccagcaatccgcgcgccgggacagaatgcc
     ctgcaggaacttcttctggaagaccttctcctcctgcaaataaaacctcacccatgaatgctcacgcaag
     tttaattacagacctgaa
     

et un exemple polypeptidique (fastaxmp_pro.txt)  :


     >A2ZDX4
     MEYQGQHGGHASSRADEHGNPAVTTGNAPTGMGAGHIQEPAREDKKTDGVLRRSGSSSSSSSSEDDGMGGRRKKGIKEKI
     KEKLPGGNKGNNQQQQQEHTTTTTGGAYGPQGHDTKIATGAHGGTAATTADAGGEKKGIVDKIKEKLPGQH
     >A2ZDX6
     MENYQGQHGYGADRVDVYGNPVAGQYGGGATAPGGGHGVMGMGGHHAGAGGQFQPVKEEHKTGGILHRSGSSSSSSSSED
     DGMGGRRKKGIKEKIKEKLPGGNKGNNHQQQQMMGNTGGAYGQQGHAGMTGAGTGTGVHGAEYGNTGEKKGFMDKIKEKL
     PGQH
     >AAA33480
     MEDERNTQQHQGGEQAQDQENEVKDRGLLDSLLGRNKHDDQEKKNQQEEEELATGMEKVTVAEPDHKEEGHEAAEKKDSL
     LAKLHRTSSSSSSSSDDEEEEVIDENGEIVKRKKKGLKEKVKEKSAAHKAHDEGDHHQPGVPAPAPAPPVAVDTHAHHQE
     GEHKPHFPAPAPPPHVETHHPVVVHKIEDDDTKTQTPPQAPEEEKKGLLDKIKEKLPGGHKKPEDAAAAAAAPAVHAPPP
     PAPHAEVDVSSPDGKKGLLGKIMDKIPGYHKSSGEEDRKDAAGEHKTSS
     >AAB18201
     MEDERSTQSYQGGEAAEQVEVTDRGLLGNLLGKKKAEEDKEKKEEELVTGMEKVSVEEPEVKKEEHVDGEKKETLFSKLH
     RSSSSSSSSSDEEEEEVIDDNGEVIKRKKKKGLKEKLQEKLPGHKDTEGEHVTALPAPAAPASVQTHHDTDVVVEKIDGD
     VKTEATPAVPEEEKKGFLEKIKEKLPGGHKKPEDAAAVPVTHAAPAPVTHAAPAPVHAPAPAAEEVSSPDAKEKKGLLGK
     IMDKLPGYHKTGEEDKAAAATGEHKPSA
     >AAB18202
     MEDERSTQSYQGGEAAEQVEVTDRGLLGNLLGKKKAEEDKEKQEELVTGMEKVSVEEPEVKKEEHEDGEKKETLFSKLHR
     SSSSSSSSSDEEEEEVIDDNGEVIKRKKKKGLKEKLKEKLPGHKDTEGEHVTGLPAPAAPASVQTHHDTDVVVEKIDGDV
     KTEAAPAVPEEEKKGFLEKIKEKLPGGHKKPEDAAPVPVTHAAPAPVHAPAPAAEEVSSPDAKEKKGLLGKIMDKLPGYH
     KTGEEDKAAAAAGEHKPSA
     

Le plus gros reproche qu'on peut faire à ce format, très simple et encore très utilisé en 2012, est qu'il n'autorise pas l'écriture de commentaires.

Dans une version plus développée, une séquence peut comporter une longueur de séquence, une ou plusieurs indications de dates, une ou plusieurs indications d'auteurs et d'articles, les valeurs d'autres identifiants pour les autres base de données bioinformatiques, la taxonomie liée au gène, à la protéine ou à l'organisme hôte ou cible, des descriptions de portions codantes, etc.

A l'usage, il semble bien que les formats XML retenus par les grands organismes comme le NCBI, UNIPROT ou l'EBI et son ENA utilisent majoritairement des éléments et non pas des attributs pour la séquence. Ainsi on trouve presque exclusivement ce que nous nommerons le format fastaXmlElt dont voici un exemple (fastaxmpelt.xml) :


     <?xml version="1.0" ?>
     <!-- Fichier fastaxmpelt.xml -->
     <proteins>
        <protein>
           <identifiant>A2ZDX4</identifiant>
           <sequence>
              MEYQGQHGGHASSRADEHGNPAVTTGNAPTGMGAGHIQEPAREDKKTDGVLRRSGSSSSSSSSEDDGMGGRRKKGIKEKI
              KEKLPGGNKGNNQQQQQEHTTTTTGGAYGPQGHDTKIATGAHGGTAATTADAGGEKKGIVDKIKEKLPGQH</sequence>
        </protein>
        <protein>
           <identifiant>A2ZDX6</identifiant>
           <sequence>
              MENYQGQHGYGADRVDVYGNPVAGQYGGGATAPGGGHGVMGMGGHHAGAGGQFQPVKEEHKTGGILHRSGSSSSSSSSED
              DGMGGRRKKGIKEKIKEKLPGGNKGNNHQQQQMMGNTGGAYGQQGHAGMTGAGTGTGVHGAEYGNTGEKKGFMDKIKEKL
              PGQH
           </sequence>
        </protein>
        <protein>
           <identifiant>AAA33480</identifiant>
           <sequence>
              MEDERNTQQHQGGEQAQDQENEVKDRGLLDSLLGRNKHDDQEKKNQQEEEELATGMEKVTVAEPDHKEEGHEAAEKKDSL
              LAKLHRTSSSSSSSSDDEEEEVIDENGEIVKRKKKGLKEKVKEKSAAHKAHDEGDHHQPGVPAPAPAPPVAVDTHAHHQE
              GEHKPHFPAPAPPPHVETHHPVVVHKIEDDDTKTQTPPQAPEEEKKGLLDKIKEKLPGGHKKPEDAAAAAAAPAVHAPPP
              PAPHAEVDVSSPDGKKGLLGKIMDKIPGYHKSSGEEDRKDAAGEHKTSS
           </sequence>
        </protein>
        <protein>
           <identifiant>AAB18201</identifiant>
           <sequence>
              MEDERSTQSYQGGEAAEQVEVTDRGLLGNLLGKKKAEEDKEKKEEELVTGMEKVSVEEPEVKKEEHVDGEKKETLFSKLH
              RSSSSSSSSSDEEEEEVIDDNGEVIKRKKKKGLKEKLQEKLPGHKDTEGEHVTALPAPAAPASVQTHHDTDVVVEKIDGD
              VKTEATPAVPEEEKKGFLEKIKEKLPGGHKKPEDAAAVPVTHAAPAPVTHAAPAPVHAPAPAAEEVSSPDAKEKKGLLGK
              IMDKLPGYHKTGEEDKAAAATGEHKPSA
           </sequence>
        </protein>
        <protein>
           <identifiant>AAB18202</identifiant>
           <sequence>
              MEDERSTQSYQGGEAAEQVEVTDRGLLGNLLGKKKAEEDKEKQEELVTGMEKVSVEEPEVKKEEHEDGEKKETLFSKLHR
              SSSSSSSSSDEEEEEVIDDNGEVIKRKKKKGLKEKLKEKLPGHKDTEGEHVTGLPAPAAPASVQTHHDTDVVVEKIDGDV
              KTEAAPAVPEEEKKGFLEKIKEKLPGGHKKPEDAAPVPVTHAAPAPVHAPAPAAEEVSSPDAKEKKGLLGKIMDKLPGYH
              KTGEEDKAAAAAGEHKPSA
           </sequence>
        </protein>
     </proteins>
     

plutôt que le format que nous nommerons fastaXmlAtt comme ci-dessous (fastaxmpatt.xml) :


     <?xml version="1.0" encoding="UTF-8" ?>
     <!-- Fichier fastaxmpatt.xml -->
     <proteins>
        <protein identifiant="A2ZDX4"
                 sequence="MEYQGQHGGHASSRADEHGNPAVTTGNAPTGMGAGHIQEPAREDKKTDGVLRRSGSSSSSSSSEDDGMGGRRKKGIKEKI
                        KEKLPGGNKGNNQQQQQEHTTTTTGGAYGPQGHDTKIATGAHGGTAATTADAGGEKKGIVDKIKEKLPGQH"
         />
        <protein identifiant="A2ZDX6"
                 sequence="MENYQGQHGYGADRVDVYGNPVAGQYGGGATAPGGGHGVMGMGGHHAGAGGQFQPVKEEHKTGGILHRSGSSSSSSSSED
                        DGMGGRRKKGIKEKIKEKLPGGNKGNNHQQQQMMGNTGGAYGQQGHAGMTGAGTGTGVHGAEYGNTGEKKGFMDKIKEKL
                        PGQH"
         />
        <protein identifiant="AAA33480"
                 sequence="MEDERNTQQHQGGEQAQDQENEVKDRGLLDSLLGRNKHDDQEKKNQQEEEELATGMEKVTVAEPDHKEEGHEAAEKKDSL
                        LAKLHRTSSSSSSSSDDEEEEVIDENGEIVKRKKKGLKEKVKEKSAAHKAHDEGDHHQPGVPAPAPAPPVAVDTHAHHQE
                        GEHKPHFPAPAPPPHVETHHPVVVHKIEDDDTKTQTPPQAPEEEKKGLLDKIKEKLPGGHKKPEDAAAAAAAPAVHAPPP
                        PAPHAEVDVSSPDGKKGLLGKIMDKIPGYHKSSGEEDRKDAAGEHKTSS"
         />
        <protein identifiant="AAB18201"
                 sequence="MEDERSTQSYQGGEAAEQVEVTDRGLLGNLLGKKKAEEDKEKKEEELVTGMEKVSVEEPEVKKEEHVDGEKKETLFSKLH
                        RSSSSSSSSSDEEEEEVIDDNGEVIKRKKKKGLKEKLQEKLPGHKDTEGEHVTALPAPAAPASVQTHHDTDVVVEKIDGD
                        VKTEATPAVPEEEKKGFLEKIKEKLPGGHKKPEDAAAVPVTHAAPAPVTHAAPAPVHAPAPAAEEVSSPDAKEKKGLLGK
                        IMDKLPGYHKTGEEDKAAAATGEHKPSA"
         />
        <protein identifiant="AAB18202"
                 sequence="MEDERSTQSYQGGEAAEQVEVTDRGLLGNLLGKKKAEEDKEKQEELVTGMEKVSVEEPEVKKEEHEDGEKKETLFSKLHR
                        SSSSSSSSSDEEEEEVIDDNGEVIKRKKKKGLKEKLKEKLPGHKDTEGEHVTGLPAPAAPASVQTHHDTDVVVEKIDGDV
                        KTEAAPAVPEEEKKGFLEKIKEKLPGGHKKPEDAAPVPVTHAAPAPVHAPAPAAEEVSSPDAKEKKGLLGKIMDKLPGYH
                        KTGEEDKAAAAAGEHKPSA"
         />
     </proteins>
     

Afin de repérer facilement des séquences considéres considérées comme communes, il est d'usage d'ajouter une indication de classe (ou "groupe"). Par exemple, le fichier suivant, au format fasta traditionnel, permet de distinguer 2 protéines de classe 1 et 3 protéines de classe 2 via l'indication sur la ligne de l'identifiant après le symbole | (ou "pipe")  (fastacl1.txt) :


     >A2ZDX4   | Class 1
     MEYQGQHGGHASSRADEHGNPAVTTGNAPTGMGAGHIQEPAREDKKTDGVLRRSGSSSSSSSSEDDGMGGRRKKGIKEKI
     KEKLPGGNKGNNQQQQQEHTTTTTGGAYGPQGHDTKIATGAHGGTAATTADAGGEKKGIVDKIKEKLPGQH
     >A2ZDX6   | Class 1
     MENYQGQHGYGADRVDVYGNPVAGQYGGGATAPGGGHGVMGMGGHHAGAGGQFQPVKEEHKTGGILHRSGSSSSSSSSED
     DGMGGRRKKGIKEKIKEKLPGGNKGNNHQQQQMMGNTGGAYGQQGHAGMTGAGTGTGVHGAEYGNTGEKKGFMDKIKEKL
     PGQH
     >AAA33480 | Class 2
     MEDERNTQQHQGGEQAQDQENEVKDRGLLDSLLGRNKHDDQEKKNQQEEEELATGMEKVTVAEPDHKEEGHEAAEKKDSL
     LAKLHRTSSSSSSSSDDEEEEVIDENGEIVKRKKKGLKEKVKEKSAAHKAHDEGDHHQPGVPAPAPAPPVAVDTHAHHQE
     GEHKPHFPAPAPPPHVETHHPVVVHKIEDDDTKTQTPPQAPEEEKKGLLDKIKEKLPGGHKKPEDAAAAAAAPAVHAPPP
     PAPHAEVDVSSPDGKKGLLGKIMDKIPGYHKSSGEEDRKDAAGEHKTSS
     >AAB18201 | Class 2
     MEDERSTQSYQGGEAAEQVEVTDRGLLGNLLGKKKAEEDKEKKEEELVTGMEKVSVEEPEVKKEEHVDGEKKETLFSKLH
     RSSSSSSSSSDEEEEEVIDDNGEVIKRKKKKGLKEKLQEKLPGHKDTEGEHVTALPAPAAPASVQTHHDTDVVVEKIDGD
     VKTEATPAVPEEEKKGFLEKIKEKLPGGHKKPEDAAAVPVTHAAPAPVTHAAPAPVHAPAPAAEEVSSPDAKEKKGLLGK
     IMDKLPGYHKTGEEDKAAAATGEHKPSA
     >AAB18202 | Class 2
     MEDERSTQSYQGGEAAEQVEVTDRGLLGNLLGKKKAEEDKEKQEELVTGMEKVSVEEPEVKKEEHEDGEKKETLFSKLHR
     SSSSSSSSSDEEEEEVIDDNGEVIKRKKKKGLKEKLKEKLPGHKDTEGEHVTGLPAPAAPASVQTHHDTDVVVEKIDGDV
     KTEAAPAVPEEEKKGFLEKIKEKLPGGHKKPEDAAPVPVTHAAPAPVHAPAPAAEEVSSPDAKEKKGLLGKIMDKLPGYH
     KTGEEDKAAAAAGEHKPSA
     

Toutefois, il peut être parfois plus simple de mettre le numéro de classe comme faisant partie de l'identifiant, comme suit (fastacl2.txt) :


     >A2ZDX4_1
     MEYQGQHGGHASSRADEHGNPAVTTGNAPTGMGAGHIQEPAREDKKTDGVLRRSGSSSSSSSSEDDGMGGRRKKGIKEKI
     KEKLPGGNKGNNQQQQQEHTTTTTGGAYGPQGHDTKIATGAHGGTAATTADAGGEKKGIVDKIKEKLPGQH
     >A2ZDX6_1
     MENYQGQHGYGADRVDVYGNPVAGQYGGGATAPGGGHGVMGMGGHHAGAGGQFQPVKEEHKTGGILHRSGSSSSSSSSED
     DGMGGRRKKGIKEKIKEKLPGGNKGNNHQQQQMMGNTGGAYGQQGHAGMTGAGTGTGVHGAEYGNTGEKKGFMDKIKEKL
     PGQH
     >AAA33480_2
     MEDERNTQQHQGGEQAQDQENEVKDRGLLDSLLGRNKHDDQEKKNQQEEEELATGMEKVTVAEPDHKEEGHEAAEKKDSL
     LAKLHRTSSSSSSSSDDEEEEVIDENGEIVKRKKKGLKEKVKEKSAAHKAHDEGDHHQPGVPAPAPAPPVAVDTHAHHQE
     GEHKPHFPAPAPPPHVETHHPVVVHKIEDDDTKTQTPPQAPEEEKKGLLDKIKEKLPGGHKKPEDAAAAAAAPAVHAPPP
     PAPHAEVDVSSPDGKKGLLGKIMDKIPGYHKSSGEEDRKDAAGEHKTSS
     >AAB18201_2
     MEDERSTQSYQGGEAAEQVEVTDRGLLGNLLGKKKAEEDKEKKEEELVTGMEKVSVEEPEVKKEEHVDGEKKETLFSKLH
     RSSSSSSSSSDEEEEEVIDDNGEVIKRKKKKGLKEKLQEKLPGHKDTEGEHVTALPAPAAPASVQTHHDTDVVVEKIDGD
     VKTEATPAVPEEEKKGFLEKIKEKLPGGHKKPEDAAAVPVTHAAPAPVTHAAPAPVHAPAPAAEEVSSPDAKEKKGLLGK
     IMDKLPGYHKTGEEDKAAAATGEHKPSA
     >AAB18202_2
     MEDERSTQSYQGGEAAEQVEVTDRGLLGNLLGKKKAEEDKEKQEELVTGMEKVSVEEPEVKKEEHEDGEKKETLFSKLHR
     SSSSSSSSSDEEEEEVIDDNGEVIKRKKKKGLKEKLKEKLPGHKDTEGEHVTGLPAPAAPASVQTHHDTDVVVEKIDGDV
     KTEAAPAVPEEEKKGFLEKIKEKLPGGHKKPEDAAPVPVTHAAPAPVHAPAPAAEEVSSPDAKEKKGLLGKIMDKLPGYH
     KTGEEDKAAAAAGEHKPSA
     

Pour XML, le choix se pose à nouveau de faire de la classe une partie de l'identifant (fastacl01.xml), de l'implémenter comme un attribut (fastacl02.xml), ou alors de soit d'utiliser un élément (fastacl03.xml), à moins d'utiliser un "panachage" (fastacl04.xml)  :

fastacl01.xml       fastacl02.xml       fastacl03.xml       fastacl04.xml       

Enfin, les séquences étant en général de longueur variable, une indication de longueur, en élément ou attribut est souvent utile, à titre de vérification ou controle, d'où de nombreuses possibilités de stockage :

Identifiant Séquence Classe Longueur
Elément
Attribut

On pourra consulter ici le code-source PHP qui génère le fichier XML via l'API DOM de PHP 5.

2. Grammaires et vérifications

Le format Fasta est simple, et les éléments de base qu'il met en jeu (identifiant et séquence) sont peu nombreux. Toutefois, les vérifications qui s'imposent, notamment au niveau de l'alphabet pour la séquence fasta, ne peuvent pas s'écrire avec une DTD. Pour la longueur, nous essaierons de rajouter la contrainte qu'il faut au moins 20 acides aminés pour avoir une séquence polypeptitique "valide", même les grands centres autorisent le stockage de "segments" ou "portions" ou "fragments" avec moins de 20 caractères. Enfin, on admettra qu'une classe doit contenir au moins deux protéines et qu'un fichier XML de protéines doit toujours contenir au moins une protéine. Par contre, il n'est pas clair que deux identifiants distincts doivent correspondre à deux séquences distinctes et nous traiterons donc ce problème plus tard.

Afin que ce texte soit progressif et pédagogique, nous allons essayer d'exploiter au maximum les grammaires DTD avant d'utiliser les schémas XSD car les DTD sont plus simples à écrire que les XSD.

2.1 Grammaires DTD

Commençons par écrire une DTD pour le format fastaXmlElt dont fastaxmpelt.xml est un exemple. L'élément racine est proteins et il doit y avoir au moins un élément protein, d'où la déclaration 1 de fastaelt1.dtd. Chaque élément protein doit contenir dans cet ordre un élément identifiant et un élément sequence, d'où la déclaration 2. Un identifiant et une séquence sont a priori des chaines de caractères, donc une première grammaire de type DTD est simplement fastaelt1.dtd :


     <!-- Grammaire fastaelt1.dtd                -->
     
     <!ELEMENT proteins    (protein)+              >
     <!ELEMENT protein     (identifiant,sequence)  >
     <!ELEMENT identifiant (#PCDATA)               >
     <!ELEMENT sequence    (#PCDATA)               >
     

Si l'identifiant est composé d'un seul mot et est bien unique (ce qui peut ne pas être le cas quand on fusionne des fichiers XML issus de diférentes bases de données), il serait bon de pouvoir vérifier l'unicité des identifiants. Malheureusement, ceci ne peut pas s'écrire dans une DTD, pas plus que le fait que les lettres de la séquence ne sont pas toutes les lettres possibles de l'alphabet. On se contentera donc de la grammaire précédente.

Si maintenant on décide d'utiliser le format fastaXmlAtt dont fastaxmpatt.xml est un exemple, il est possible de déclarer l'identifiant comme un id au sens des DTD, sous réserve bien sûr que l'identifiant corresponde à un seul mot, d'où la grammaire fastaatt1.dtd :


     <!-- Grammaire fastaatt1.dtd                         -->
     
     <!ELEMENT proteins    (protein)+                       >
     <!ELEMENT protein                  EMPTY               >
     <!ATTLIST protein     identifiant  ID        #REQUIRED >
     <!ATTLIST protein     sequence     CDATA     #REQUIRED >
     

Avec un exemple un peu plus structuré où une séquence comporte un attribut class facultatif et un attribut longueur facultatif, comme pour fastamixte1.xml et fastamixte2.xml, on peut écrire une grammaire fastamixte1.dtd comme :


     <!-- Grammaire fastamixte1.dtd                 -->
     
     <!ELEMENT proteins     (protein)+                >
     <!ELEMENT protein      (identifiant,sequence)    >
     <!ELEMENT identifiant  (#PCDATA)                 >
     <!ELEMENT sequence     (#PCDATA)                 >
     
     <!ATTLIST protein      class     CDATA  #IMPLIED >
     <!ATTLIST sequence     longueur  CDATA  #IMPLIED >
     

Pour en finir avec les DTD, on utilise désormais un élément classe vide facultatif avec un numéro, un nom et une longueur facultatifs, comme pour fastamixte3.xml et fastamixte4.xml, d'où la grammaire fastamixte2.dtd :


     <!-- Grammaire fastamixte2.dtd                         -->
     
     <!ELEMENT proteins     (protein)+                        >
     <!ELEMENT protein      (class?,identifiant,sequence)     >
     <!ELEMENT class         EMPTY                            >
     <!ELEMENT identifiant  (#PCDATA)                         >
     <!ELEMENT sequence     (#PCDATA)                         >
     
     <!ATTLIST class         num       CDATA  #IMPLIED        >
     <!ATTLIST class         nom       CDATA  #IMPLIED        >
     <!ATTLIST sequence      longueur  CDATA  #IMPLIED        >
     

On ne confondra pas cette dernière grammaire avec celle qui impose un élément classe obligatoire avec des attributs facultatifs soit fastamixte3.dtd à tester avec fastamixte5.xml et fastamixte6.xml :


     <!-- Grammaire fastamixte3.dtd                         -->
     
     <!ELEMENT proteins     (protein+)                        >
     <!ELEMENT protein      (class,identifiant,sequence)      >
     <!ELEMENT class         EMPTY                            >
     <!ELEMENT identifiant  (#PCDATA)                         >
     <!ELEMENT sequence     (#PCDATA)                         >
     
     <!ATTLIST class         num       CDATA  #IMPLIED        >
     <!ATTLIST class         nom       CDATA  #IMPLIED        >
     <!ATTLIST sequence      longueur  CDATA  #IMPLIED        >
     

2.2 Grammaires XSD

Reprenons le format fastaXmlElt dont fastaxmpelt.xml est un exemple. L'élément racine est proteins et il doit y avoir au moins un élément protein, d'où le texte maxOccurs="unbounded" car minOccurs="1" est la valeur par défaut. Chaque élément protein doit contenir dans cet ordre un élément identifiant et un élément sequence, d'où la deuxième construction <xsd:complexType><xsd:sequence>. Un identifiant et une séquence sont a priori des chaines de caractères, donc une première grammaire de type XSD est simplement fastaelt1.xsd, copiée sur le modèle de fastaelt1.dtd :


     <?xml version="1.0" ?><!-- Fichier fastaelt1.xsd -->
     
     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
     
     <xsd:element name="proteins">
       <xsd:complexType>
           <xsd:sequence>
             <xsd:element name="protein" maxOccurs="unbounded">
                <xsd:complexType>
                   <xsd:sequence>
                      <xsd:element name="identifiant" type="xsd:string" />
                      <xsd:element name="sequence"    type="xsd:string" />
                   </xsd:sequence>
                </xsd:complexType>
             </xsd:element>
          </xsd:sequence>
       </xsd:complexType>
     </xsd:element>
     
     </xsd:schema>
     

Pour profiter pleinement de XSD, nous allons commencer par séparer la définition des éléments identifiant et sequence. Pour cela, on utilise <xsd:element ref="identifiant" /> au lieu de <xsd:element name="identifiant" /> en rajoutant en fin de fichier la définition de identifiant. On procède de façon identique pour sequence :


     <?xml version="1.0" ?><!-- Fichier fastaelt2.xsd -->
     
     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
     
     <xsd:element name="proteins">
       <xsd:complexType>
           <xsd:sequence>
             <xsd:element name="protein" maxOccurs="unbounded">
                <xsd:complexType>
                   <xsd:sequence>
                      <xsd:element ref="identifiant" />
                      <xsd:element ref="sequence"    />
                   </xsd:sequence>
                </xsd:complexType>
             </xsd:element>
          </xsd:sequence>
       </xsd:complexType>
     </xsd:element>
     
     <xsd:element name="identifiant" type="xsd:string" />
     <xsd:element name="sequence"    type="xsd:string" />
     
     </xsd:schema>
     

Rajoutons maintenant nos contraintes initiales, à savoir une séquence a une longueur de 20 caractères au moins, et ses lettres font partie de ACDEFGHIKLMNPQRSTVWY seulement. Une grammaire comme fastaelt3.xsd déclare invalide notre fichier initial fastaxmpelt.xml (astucieusement recopié en fastaxmpelt.txt) car il contient des espaces, des retours-charriot. Un "vrai" fichier XML valide pour cette grammaire est fastaxmpelt2.xml qui se voit bien une fois recopié en fastaxmpelt2.txt.


     <?xml version="1.0" ?><!-- Fichier fastaelt3.xsd -->
     
     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
     
     <xsd:element name="proteins">
       <xsd:complexType>
           <xsd:sequence>
             <xsd:element name="protein" maxOccurs="unbounded">
                <xsd:complexType>
                   <xsd:sequence>
                      <xsd:element ref="identifiant" />
                      <xsd:element ref="sequence"    />
                   </xsd:sequence>
                </xsd:complexType>
             </xsd:element>
          </xsd:sequence>
       </xsd:complexType>
     </xsd:element>
     
     <xsd:element name="identifiant" type="xsd:string" />
     
     <xsd:simpleType name="sequenceAA">
       <xsd:restriction base="xsd:string">
         <xsd:minLength value="20" />
         <xsd:pattern   value="[ACDEFGHIKLMNPQRSTVWY]+" />
       </xsd:restriction>
     </xsd:simpleType>
     
     <xsd:element name="sequence" type="sequenceAA" />
     
     </xsd:schema>
     

Reprenons l'exemple un peu plus structuré où une séquence comporte un attribut class facultatif et un attribut longueur facultatif, comme pour fastamixte7.xml et fastamixte8.xml. Une première grammaire possible est fastaelt4.xsd :


     <?xml version="1.0" ?><!-- Fichier fastaelt4.xsd -->
     
     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
     
     <xsd:element name="proteins">
       <xsd:complexType>
           <xsd:sequence>
     
             <xsd:element name="protein" maxOccurs="unbounded">
                <xsd:complexType>
                   <xsd:sequence>
                      <xsd:element ref="identifiant" />
                      <xsd:element ref="sequence"    />
                   </xsd:sequence>
                   <xsd:attribute ref="class" use="optional" />
                </xsd:complexType>
             </xsd:element>
     
          </xsd:sequence>
       </xsd:complexType>
     </xsd:element>
     
     <xsd:element name="identifiant" type="xsd:string" />
     <xsd:element name="sequence"    type="sequenceAvecLongueurFacultative" />
     
     <xsd:simpleType name="sequenceAA">
       <xsd:restriction base="xsd:string">
         <xsd:minLength value="20" />
         <xsd:pattern   value="[ACDEFGHIKLMNPQRSTVWY]+" />
       </xsd:restriction>
     </xsd:simpleType>
     
     <xsd:simpleType name="nosLongueurs">
       <xsd:restriction base="xsd:nonNegativeInteger">
         <xsd:minInclusive value="20" />
       </xsd:restriction>
     </xsd:simpleType>
     
     <xsd:complexType name="sequenceAvecLongueurFacultative">
        <xsd:simpleContent>
           <xsd:extension base="sequenceAA">
             <xsd:attribute ref="longueur" use="optional" />
           </xsd:extension>
        </xsd:simpleContent>
     </xsd:complexType>
     
     <xsd:attribute name="class"     type="xsd:nonNegativeInteger" />
     <xsd:attribute name="longueur"  type="nosLongueurs" />
     
     </xsd:schema>
     

Toutefois, il est dommage d'avoir à copier/coller notre définition de sequenceAA. Il est beaucoup plus intéressant de mettre cette définition dans un autre fichier, disons bioinfdefs.xsd et d'inclure ce fichier dans la grammaire, soit le fichier fastaelt5.xsd :


     <?xml version="1.0" ?><!-- Fichier Fastaelt5.xsd -->
     
     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
     <xsd:include schemaLocation="bioinfdefs.xsd" />
     
     <xsd:element name="proteins">
       <xsd:complexType>
           <xsd:sequence>
     
             <xsd:element name="protein" maxOccurs="unbounded">
                <xsd:complexType>
                   <xsd:sequence>
                      <xsd:element ref="identifiant" />
                      <xsd:element ref="sequence"    />
                   </xsd:sequence>
                   <xsd:attribute ref="class" use="optional" />
                </xsd:complexType>
             </xsd:element>
     
          </xsd:sequence>
       </xsd:complexType>
     </xsd:element>
     
     <xsd:element name="identifiant" type="xsd:string" />
     
     <xsd:element name="sequence"    type="sequenceAvecLongueurFacultative" />
     
     <xsd:attribute name="class"     type="xsd:nonNegativeInteger" />
     
     <!-- inutile car incluse, mais utile pour rappeler qu'il
          existe un attribut longueur
     
          <xsd:attribute name="longueur"  type="nosLongueurs" />
     -->
     
     </xsd:schema>
     

2.3 Exemple de script de vérification :


     # Fichier cmdsval.txt
     
     ## Fichiers conformes
     
     xmlstarlet val -w fastaxmpelt.xml
     xmlstarlet val -w fastaxmpatt.xml
     
     xmlstarlet val -w fastacl01.xml
     xmlstarlet val -w fastacl02.xml
     xmlstarlet val -w fastacl03.xml
     
     xmlstarlet val -w fastamixte1.xml
     xmlstarlet val -w fastamixte2.xml
     xmlstarlet val -w fastamixte3.xml
     xmlstarlet val -w fastamixte4.xml
     xmlstarlet val -w fastamixte5.xml
     xmlstarlet val -w fastamixte6.xml
     xmlstarlet val -w fastamixte7.xml
     xmlstarlet val -w fastamixte8.xml
     
     xmlstarlet val -w fastaxmpelt2.xml
     
     
     ## DTDs
     
     xmllint --noout --dtdvalid fastaelt1.dtd   fastaxmpelt.xml
     xmllint --noout --dtdvalid fastaatt1.dtd   fastaxmpatt.xml
     xmllint --noout --dtdvalid fastamixte1.dtd fastamixte2.xml
     
     xmllint --noout --dtdvalid fastamixte2.dtd fastamixte3.xml
     xmllint --noout --dtdvalid fastamixte2.dtd fastamixte4.xml
     
     xmllint --noout --dtdvalid fastamixte3.dtd fastamixte5.xml
     xmllint --noout --dtdvalid fastamixte3.dtd fastamixte6.xml
     
     # la commande suivante provoque une erreur (volontairement)
     
     xmllint --noout --dtdvalid fastamixte3.dtd fastamixte4.xml
     
     
     ## XSDs
     
     xmllint --noout --schema fastaelt1.xsd  fastaxmpelt.xml
     xmllint --noout --schema fastaelt2.xsd  fastaxmpelt.xml
     
     # la commande suivante provoque une erreur (volontairement)
     
     xmllint --noout --schema fastaelt3.xsd  fastaxmpelt.xml
     
     xmllint --noout --schema fastaelt3.xsd  fastaxmpelt2.xml
     
     xmllint --noout --schema fastaelt4.xsd  fastaxmpelt7.xml
     
     xmllint --noout --schema fastaelt4.xsd  fastaxmpelt8.xml
     
     xmllint --noout --schema fastaelt5.xsd  fastaxmpelt8.xml
     
     
     

3. Transformations simples

Il n'est pas possible de passer de fastaxmp_pro.txt (format fasta texte traditionnel) à fastaxmpelt.xml (format fasta XML avec éléments) ou à fastaxmpatt.xml (format fasta XML avec attributs) puisque le fichier d'entrée n'est pas au format XML. Par contre les transformations inverses sont possibles et faciles à écrire. De même, passer du format élément au format attribut et réciproquement est très simple, au moins au départ, car obtenir des fichiers "proprement indentés" requiert plus de finesse :

 

   Du format fastaXmlAtt au format fastaXmlElt    Du format fastaXmlElt au format fastaXmlAtt

     <?xml version="1.0" encoding="ISO-8859-1" ?>
     <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version="1.0">
     <!-- Fichier att2elt.xsl -->
     <!-- conversion d'attributs en éléments version 1, voir aussi att2eltv2.xsl -->
     
     <xsl:output method="xml" encoding="UTF-8" />
     
     <xsl:template match="/">
        <xsl:element name="proteines">
           <xsl:apply-templates match="protein" />
        </xsl:element>
     </xsl:template>
     
     <xsl:template match="protein">
        <xsl:element name="proteine">
           <xsl:element name="identifiant">
              <xsl:value-of select="@identifiant" />
           </xsl:element>
           <xsl:element name="sequence">
              <xsl:value-of select="@sequence" />
           </xsl:element>
        </xsl:element>
     </xsl:template>
     
     </xsl:stylesheet>
     

     <?xml version="1.0" encoding="ISO-8859-1" ?>
     <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version="1.0">
     <!-- Fichier elt2att.xsl -->
     <!-- conversion d'éléments en attributs -->
     
     <xsl:output method="xml" encoding="UTF-8" />
     
     <xsl:template match="/">
        <xsl:element name="proteines">
           <xsl:apply-templates match="protein" />
        </xsl:element>
     </xsl:template>
     
     <xsl:template match="protein">
        <xsl:element name="proteine">
           <xsl:attribute name="identifiant">
              <xsl:value-of select="identifiant" />
           </xsl:attribute>
           <xsl:attribute name="sequence">
              <xsl:value-of select="translate(sequence,'&#x20;&#x9;&#xD;&#xA;','')" />
           </xsl:attribute>
        </xsl:element>
     </xsl:template>
     
     </xsl:stylesheet>
     
   Du format fastaXmlAtt au format fasta texte traditionnel    Du format fastaXmlElt au format fasta texte traditionnel

     <?xml version="1.0" encoding="ISO-8859-1" ?>
     <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version="1.0">
     <!-- Fichier att2txt.xsl -->
     <!-- conversion d'attributs au format texte version 1, voir aussi att2txtv2.xsl -->
     
     <xsl:output method="text" encoding="UTF-8" />
     
     <xsl:template match="protein">
     <xsl:text>&gt;</xsl:text>
     <xsl:value-of select="@identifiant" />
     <xsl:text>
     </xsl:text>	
     <xsl:value-of select="@sequence" />
     </xsl:template>
     
     </xsl:stylesheet>
     

     <?xml version="1.0" encoding="ISO-8859-1" ?>
     <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version="1.0">
     <!-- Fichier elt2txt.xsl -->
     <!-- conversion d'éléments au format texte version 1, voir aussi elt2txtv2.xsl -->
     
     <xsl:output method="text" encoding="UTF-8" />
     
     <xsl:template match="protein">
     <xsl:text>&gt;</xsl:text>
     <xsl:value-of select="identifiant" />
     <xsl:text>
     </xsl:text>	
     <xsl:value-of select="sequence" />
     </xsl:template>
     
     </xsl:stylesheet>
     

On testera avec attention la progression des transformations att2eltv1.xsl, att2eltv2.xslet att2eltv3.xsl afin de comprendre comment on peut raffiner une solution, pour passer de att2eltv1_res.xml à att2eltv2_res.xml et att2eltv3_res.xml.

Pour vérifier la validité des fichiers produits, on pourra utiliser la grammaire fastaelte1.dtd pour laquelle l'élément racine proteines (donc avec un "e" en plus) contient des éléments proteines (donc avec un "e" en plus aussi).

D'autres transformations simples à effectuer sont celles qui consistent 

  • à convertir et supprimer la classe en fin d'identifiant dans fastacl01.xml pour en faire un élément class via cu2ec.xsl

    
         <?xml version="1.0" encoding="ISO-8859-1" ?>
         <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version="1.0">
         <!-- Fichier cu2ec.xsl -->
         
         <!-- on passe de
            <protein>
              <identifiant>A2ZDX4_1</identifiant>
              ...
            à 
            <protein>
              <identifiant>A2ZDX4</identifiant>
              <class>1</class>
              ...
         
         -->
         
         <!-- le fichier inclus contient entre autres sdl (saut de ligne) -->
         <xsl:import href="stdWeb.xsl" />
         
         <xsl:output method="xml" encoding="UTF-8" />
         
         <xsl:template match="proteins">
            <proteins>
               <xsl:call-template name="sdl" />
               <xsl:for-each select="protein">
                  <protein>
                     <xsl:call-template name="sdl" />
                     <identifiant>
                        <xsl:value-of select="substring-before(identifiant,'_')" />
                     </identifiant>
                     <xsl:call-template name="sdl" />
                     <class>
                        <xsl:value-of select="substring-after(identifiant,'_')" />
                     </class>
                     <xsl:call-template name="sdl" />
                     <sequence>
                        <xsl:value-of select="sequence" />
                     </sequence>
                     <xsl:call-template name="sdl" />
                  </protein>
                  <xsl:call-template name="sdl" />
               </xsl:for-each>
            </proteins>
         </xsl:template>
         </xsl:stylesheet>
         
    

    Fichier résultat de la transformation : cu2ec_res.xml.

  • à convertir et supprimer l'attribut classe dans fastacl02.xml pour l'ajouter à l'identifiant via attaddclass.xsl

    
         <?xml version="1.0" encoding="ISO-8859-1" ?>
         <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version="1.0">
         <!-- Fichier attaddclass.xsl -->
         
         <!-- on passe de
            <protein class="1">
              <identifiant>A2ZDX4</identifiant>
              <sequence>
              ...
            à 
            <protein>
              <identifiant>A2ZDX4_1</identifiant>
              <sequence>
              ...
         -->
         
         <!-- le fichier inclus contient entre autres sdl (saut de ligne) -->
         <xsl:import href="stdWeb.xsl" />
         
         <xsl:output method="xml" encoding="UTF-8" />
         
         <xsl:template match="proteins">
            <proteins>
               <xsl:call-template name="sdl" />
               <xsl:for-each select="protein">
                  <protein>
                     <xsl:call-template name="sdl" />
                     <identifiant>
                        <xsl:value-of select="concat(identifiant,'_',@class)" />
                     </identifiant>
                     <xsl:call-template name="sdl" />
                     <sequence>
                        <xsl:value-of select="sequence" />
                     </sequence>
                     <xsl:call-template name="sdl" />
                  </protein>
                  <xsl:call-template name="sdl" />
               </xsl:for-each>
            </proteins>
         </xsl:template>
         </xsl:stylesheet>
         
    

    Fichier résultat de la transformation : attaddclass_res.xml.

  • à calculer et ajouter la longueur de la séquence dans fastacl03.xml en tant qu'élément via eltaddlng.xsl

    
         <?xml version="1.0" encoding="ISO-8859-1" ?>
         <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version="1.0">
         <!-- Fichier eltaddlng.xsl -->
         
         <!-- on passe de
            <protein>
              <identifiant>A2ZDX4</identifiant>
              <class>1</class>
              <sequence>
              ...
            à 
            <protein>
              <identifiant>A2ZDX4</identifiant>
              <class>1</class>
              <longueur>171</longueur>
              <sequence>
              ...
         -->
         
         <!-- le fichier inclus contient entre autres sdl (saut de ligne) -->
         <xsl:import href="stdWeb.xsl" />
         
         <xsl:output method="xml" encoding="UTF-8" />
         
         <xsl:template match="proteins">
            <proteins>
               <xsl:call-template name="sdl" />
               <xsl:for-each select="protein">
                  <protein>
                     <xsl:call-template name="sdl" />
                     <identifiant>
                        <xsl:value-of select="identifiant" />
                     </identifiant>
                     <xsl:call-template name="sdl" />
                     <class>
                        <xsl:value-of select="class" />
                     </class>
                     <xsl:call-template name="sdl" />
                     <longueur>
                        <xsl:value-of select="string-length(sequence)" />
                     </longueur>
                     <xsl:call-template name="sdl" />
                     <sequence>
                        <xsl:value-of select="sequence" />
                     </sequence>
                     <xsl:call-template name="sdl" />
                  </protein>
                  <xsl:call-template name="sdl" />
               </xsl:for-each>
            </proteins>
         </xsl:template>
         </xsl:stylesheet>
         
    

    Fichier résultat de la transformation : eltaddlng_res.xml.

  • à calculer et ajouter la longueur de la séquence dans fastacl04.xml en tant qu'attribut via attaddlng.xsl

    
         <?xml version="1.0" encoding="ISO-8859-1" ?>
         <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version="1.0">
         <!-- Fichier attaddlngv2.xsl -->
         
         <!-- on passe de
            <protein>
              <identifiant>A2ZDX4</identifiant>
              <class num="1" />
              <sequence>
              ...
            à 
            <protein>
              <identifiant>A2ZDX4</identifiant>
              <class>1</class>
              <sequence longueur="171">
              ...
         -->
         
         <!-- le fichier inclus contient entre autres sdl (saut de ligne) -->
         <xsl:import href="stdWeb.xsl" />
         
         <xsl:output method="xml" encoding="UTF-8" />
         
         <xsl:template match="proteins">
            <proteins>
               <xsl:call-template name="sdl" />
               <xsl:for-each select="protein">
                  <protein>
                     <xsl:call-template name="sdl" />
                     <identifiant>
                        <xsl:value-of select="identifiant" />
                     </identifiant>
                     <xsl:call-template name="sdl" />
                     <class>
                        <xsl:value-of select="class/@num" />
                     </class>
                     <xsl:call-template name="sdl" />
         
         <!--
         
              ## ce qui suit n'est pas optimisé car on utilise deux fois translate()
         
                     <xsl:element name="sequence">
                        <xsl:attribute name="longueur">
                           <xsl:value-of select="string-length(translate(sequence,' ',''))" />
                        </xsl:attribute>
                        <xsl:value-of select="translate(sequence,' ','')" />
                     </xsl:element>
         
              ## il vaut mieux définir une variable qui contient le résultat de translate :
         
         -->
                     <xsl:variable name="nouvelleSequence" select="translate(./sequence,' ','')" />
                     <xsl:element name="sequence">
                        <xsl:attribute name="longueur">
                           <xsl:value-of select="string-length($nouvelleSequence)" />
                        </xsl:attribute>
                        <xsl:value-of select="$nouvelleSequence" />
                     </xsl:element>
                     <xsl:call-template name="sdl" />
                  </protein>
                  <xsl:call-template name="sdl" />
               </xsl:for-each>
            </proteins>
         </xsl:template>
         </xsl:stylesheet>
         
    

    Fichier résultat de la transformation : eltaddlng_res.xml.

Enfin, Excel et Open Office Calc savent lire les fichiers-texte délimités par des points-virgules. On vérifiera que la transformation att2csv.xsl appliquée au fichier icls_att.xml produit le fichier convatt.csv et qu'il est directement utilisable sous Excel et OpenOffice (on a tronqué les séquences pour plus de lisibilité).


     <?xml version="1.0" encoding="UTF-8"?>
     <!-- Fichier icls_att.xml -->
     <proteins>
        <protein identifiant="XA2ZDX4"   classe="1" longueur="15"  sequence="MEYQGQHGGHASSR"  />
        <protein identifiant="XA2ZDX6"   classe="1" longueur="16"  sequence="MENYQGQHGYGADRV" />
        <protein identifiant="XAAA33480" classe="2" longueur="14"  sequence="MEDERNTQQHQGG"   />
        <protein identifiant="XAAB18201" classe="2" longueur="12"  sequence="MEDERSTQSYQ"     />
        <protein identifiant="XAAB18202" classe="2" longueur="15"  sequence="MEDERSTQSYQGGE"  />
     </proteins>
     

     <?xml version="1.0" encoding="ISO-8859-1" ?>
     <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version="1.0">
     <!-- Fichier att2csv.xsl -->
     <!-- conversion d'attributs au format CSV pour excel -->
     
     <!-- le fichier inclus contient entre autres sdl (saut de ligne) -->
     <xsl:import href="stdWeb.xsl" />
     
     <xsl:output method="text" encoding="ISO8859-15" />
     
     
     <xsl:template match="proteins">
     
        <!-- une ligne d'en-tête pour Excel -->
     
        <xsl:text>identifiant ; classe ; longueur ; séquence AA </xsl:text>
        <xsl:call-template name="sdl" />
     
        <!-- puis toutes les informations séparées par des points-virgules -->
     
        <xsl:for-each select="protein">
     
            <xsl:value-of select="@identifiant" />
            <xsl:text> ; </xsl:text>
     
            <xsl:value-of select="@classe" />
            <xsl:text> ; </xsl:text>
     
            <xsl:value-of select="@longueur" />
            <xsl:text> ; </xsl:text>
     
            <xsl:value-of select="translate(@sequence,' ','')" />
           <xsl:call-template name="sdl" />
     
        </xsl:for-each>
     
     </xsl:template>
     
     </xsl:stylesheet>
     

     identifiant ; classe ; longueur ; séquence AA 
     XA2ZDX4 ; 1 ; 15 ; MEYQGQHGGHASSR
     XA2ZDX6 ; 1 ; 16 ; MENYQGQHGYGADRV
     XAAA33480 ; 2 ; 14 ; MEDERNTQQHQGG
     XAAB18201 ; 2 ; 12 ; MEDERSTQSYQ
     XAAB18202 ; 2 ; 15 ; MEDERSTQSYQGGE
     

On remarquera que la sortie est en ISO8859-15 pour Excel.

4. Fichiers XML des grands centres de bioinformatique

Chaque grand centre (NCBI, UNIPROT, EMBL...) a son propre format, sa propre stratégie de gestion, ses outils et ses API.

Quelques exemples

Voir également la question 7 de WEBrd01.

 

 

retour gH    Retour à la page principale de   (gH)