Fusionner des fichiers XML

Je réponds initialement ici à une question concernant TACT, la plateforme de Transcription et d’Annotation de Corpus Textuels mise à disposition par ELAN. TACT permet d’exporter ses transcriptions sous la forme d’un ensemble de fichiers zippés, mais ne permet pas de les fusionner au sein d’un seul et même fichier. Cela dit, un post-traitement est tout à fait possible. Alors que vous utilisiez TACT ou pas, si vous souhaitez regrouper plusieurs fichiers TEI en un seul, ce billet est là pour vous !

Votre besoin ?

  • S’il s’agit uniquement de coller des fichiers les uns après les autres, une simple ligne de commande sous linux est possible (sans linux, il faudrait chercher une solution sur Internet ou bien utiliser la méthode XSLT).
  • S’il s’agit de coller certains fichiers seulement, ou bien une partie des contenus XML de fichiers, ou encore d’opérer du nettoyer ou autre transformation au passage, une transformation XSL est possible. Bien sûr, d’autres solution à base de Python ou autre seraient possibles, mais je ne les détaille pas ici.

Concaténer des fichiers sous Linux grâce à cat

cat dossier_projet/*.xml >fusion.xml
Explications :
  • * cat permet précisément de concaténer des fichier et d’afficher le résultat. Indiquer >fusion.xml permet de rediriger la sortie standard vers le fichier fusion.xml, bref d’écrire le résultat directement dans le fichier fusion.xml
  • Pourquoi dossier_projet/*.xml ? Il s’agit là de préciser les fichiers que l’on souhaite concaténer. Ici, j’indique les fichiers du dossier “dossier_projet” dont le nom est n’importe quoi (*) et qui finit par “.xml“. Mais d’autres sélections sont possibles :
    • cat dossier_projet/* : s’applique à tous les fichiers de dossier_projet/
    • cat dossier_projet/A* : s’applique à tous les fichiers commençant par “A” (majuscule) de dossier_projet/
    • cat /home/annegf/projet/basnum/xml_from_tact/*.xml : ici, j’indique un chemin spécifique vers un dossier précis de mon ordinateur et je ne sélectionne que les fichiers xml
  • cat possède bon nombre  d’options à découvrir sur sa page de manuel (en ligne de commande, tapez man cat ou bien allez sur : https://www.man7.org/linux/man-pages/man1/cat.1.html)

Fusionner des xml en opérant des modifications grâce à XSLT

Il s’agit d’appliquer une transformation XSL, créera une collection de fichiers XML, fera un ensemble d’opération sur chacun de ces XML et sortira un résultat au format XML dans un fichier donné.

Un XSLT de base qui ne fait que coller les contenus dans un fichier de sortie est le suivant (on suppose de la TEI en entrée). Ici, on suppose que les fichiers à fusionner sont tous dans le même dossier et que la transformation s’applique à l’un d’entre eux, choisi au hasard (cela n’a pas d’importance par la suite).

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tei="http://www.tei-c.org/ns/1.0"
    xmlns="http://www.w3.org/1999/xhtml" version="2.0">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
        <xsl:for-each select="collection('.?select=*.xml')">
            <xsl:copy-of select="/"/>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

On précise que l’on veut une sortie XML grâce à <xsl:output method=“xml” indent=“yes”/>. On ne définit qu’une seule règle de transformation (<xsl:template match=“/”/>) qui – pour chaque document d’un ensemble défini grâce à collection(‘.?select=*.xml’) (tous les fichiers .xml du dossier courant, c’est-à-dire le dossier où se situe le fichier XML d’entrée) – va copier l’intégralité du nœud racine (attributs et descendants compris) grâce à “<xsl:copy-of select=“/”/>“.

Si on souhaite sélectionner certains fichiers seulement : on peut modifier la collection. Par exemple, collection(‘.?select=0123*.xml’). permet de ne traiter que les fichiers dont l’extension est .xml et qui commencent par “0123”. Si le filtre doit se faire sur le contenu des fichiers plutôt que sur leur nom, il faudra utiliser une condition dans le for-each – voir plus loin).

Si on souhaite fusionner uniquement une partie du contenu : par exemple, uniquement les contenus des <body/>, modifier le copy-of en : <xsl:copy-of select=“//tei:body/*”/>. Cela est modulable à loisir bien sûr.

Si on souhaite maîtriser l’ordre de fusion des fichiers : il conviendra d’utiliser <xsl:sort/>. Par exemple :

<xsl:sort select=“base-uri(.)” lang=“fr” order=“descending”/> permet d’ordonner selon le nom du fichier, en français (si vos noms de fichiers contiennent des accents – ce qui n’est pas recommandé mais… courant – et que vous ne précisez pas la langue, par défaut, comme en anglais les lettres accentuées sont considérées comme en fin d’alphabet) et par ordre croissant (de 0 à 9 et de A à Z).

<xsl:sort select=“/tei:TEI//tei:titleStmt/tei:title” lang=“fr”/> permet d’ordonner selon la valeur du title de titleStmt. Un exemple parmi d’autres à adapter selon les besoins.

D’autres possibilités sont permises. Voir par exemple : https://www.w3schools.com/xml/ref_xsl_el_sort.asp

Si on souhaite faire un traitement différencié selon les contenus des fichiers : on pourra utiliser des conditions dans le <xsl:for-each/>. Par exemple, si on ne souhaite fusionner que les fichiers qui possèdent un tei:front :

<xsl:for-each select="collection('.?select=0192*.xml')">
     <xsl:sort select="base-uri(.)" lang="fr" order="descending"/>
     <xsl:if test="//tei:front">
          <xsl:copy-of select="/"/>
     </xsl:if>
</xsl:for-each>

Si on ne souhaite pas fusionner les fichiers tels quels, mais transformer des choses dans l’arbre XML : il faut indiquer ses instructions et faire appels à d’autres templates éventuels à la place de <xsl:copy-of/>.

Ça pourrait durer longtemps comme ça, mais voilà déjà quelques idées et si vous avez d’autres besoins, faites-le savoir !


OpenEdition vous propose de citer ce billet de la manière suivante :
Anne Garcia-Fernandez (25 août 2023). Fusionner des fichiers XML. ELAN - L'élan littératures, arts et numériques de Litt&Arts (UMR 5316). Consulté le 19 juillet 2024 à l’adresse https://doi.org/10.58079/o5fo


Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.