Comment traduire les fichiers XLIFF (Drupal, Symfony, Angular, iOS)

La semaine dernière, une développeuse Drupal a posté sur Stack Overflow une histoire qui se répète des milliers de fois par an au sein des équipes de localisation d'entreprise. Son équipe a exporté un fichier XLIFF de 40 Mo depuis leur site Drupal. Elle l'a ouvert dans un éditeur de texte, a copié des morceaux dans Google Traduction, a réassemblé le fichier, l'a réimporté dans Drupal – et la moitié des pages ont refusé de s'afficher parce que les chaînes traduites contenaient du XML malformé, des caractères échappés aux mauvais endroits et des balises <g> cassées où le formatage en ligne avait été détruit.
XLIFF est la norme de localisation d'entreprise pour une raison. Il est basé sur XML, indépendant de l'outil et prend en charge les métadonnées riches dont les projets de traduction sérieux ont besoin : états de traduction, traductions alternatives, notes entre traducteurs et développeurs, et balisage structuré en ligne. Mais sa flexibilité même le rend facile à corrompre, et les outils qui gèrent les fichiers .po en toute sécurité échouent souvent avec XLIFF.
Ce guide explique ce qui rend XLIFF unique, pourquoi les approches de traduction génériques le cassent, et la bonne manière de traduire les fichiers XLIFF pour Drupal, Symfony, Angular et iOS – les quatre plateformes où XLIFF est le plus couramment utilisé en 2026.
Qu'est-ce que XLIFF (et pourquoi les équipes d'entreprise l'utilisent)
XLIFF signifie XML Localization Interchange File Format. C'est une norme OASIS conçue spécifiquement pour le transfert de contenu de traduction entre outils – systèmes de gestion de contenu, bases de données de mémoire de traduction, outils TAO (Traduction Assistée par Ordinateur) et plateformes de localisation. Contrairement aux fichiers Gettext .po (qui stockent des paires clé-valeur plates) ou aux fichiers de locales JSON (qui s'imbriquent arbitrairement), XLIFF est un document XML structuré avec un schéma standardisé.
XLIFF 1.2 vs XLIFF 2.0
Deux versions existent en circulation, et elles ne sont pas entièrement compatibles.
XLIFF 1.2 est la version plus ancienne et plus largement déployée. Elle utilise des éléments <trans-unit> pour encapsuler le contenu traduisible, avec des enfants <source> et <target>. Le formatage en ligne utilise les balises jumelées <g>, <x> et <bpt> / <ept>. L'outil de gestion de traduction de Drupal et de nombreuses plateformes plus anciennes exportent toujours la version 1.2.
XLIFF 2.0 est la révision de 2014, plus simple et plus propre. Elle utilise <unit> et <segment> avec <source> et <target>. Le balisage en ligne utilise <pc> (code jumelé) et <ph> (placeholder). Le composant de traduction de Symfony et les exportations iOS modernes utilisent par défaut la version 2.0.
Un outil de traduction qui gère la version 1.2 ne gère pas automatiquement la version 2.0. Les vocabulaires des balises sont différents, et les règles d'échappement diffèrent légèrement. Vérifiez toujours la version exportée par votre plateforme avant de choisir une chaîne de traduction.
L'anatomie d'une unité XLIFF
Une unité de traduction (trans-unit) XLIFF 1.2 minimale ressemble à ceci :
<trans-unit id="msg_welcome" datatype="plaintext">
<source>Welcome, <g id="1">%name%</g>!</source>
<target state="needs-translation">Welcome, <g id="1">%name%</g>!</target>
<note>Displayed on the homepage after login</note>
</trans-unit>
La balise <g id="1"> enveloppe une variable de type placeholder. L'attribut state indique à la plateforme que cette chaîne doit être traduite. La balise <note> est une indication pour le développeur. Un traducteur qui comprend XLIFF devrait produire :
<target state="translated">¡Bienvenido, <g id="1">%name%</g>!</target>
Un traducteur qui traite le fichier comme du texte brut pourrait produire l'une de ces variantes corrompues :
<target>¡Bienvenido, <g id="1">%nombre%</g>!</target>
<target>¡Bienvenido, <g id="1">%name%</g>!</target>
<target>¡Bienvenido, %name%!</target>
Chacune de ces variantes rompt l'importation différemment. La première renomme la variable. La seconde échappe le XML. La troisième supprime entièrement la balise de formatage.
Mauvaises solutions (Pourquoi vous ne pouvez pas simplement traduire du XML)
La plupart des équipes commencent par les trois mêmes approches et perdent plusieurs jours avant d'abandonner.
Alimenter XLIFF à une IA générique
Copiez le fichier, collez-le dans Claude ou ChatGPT, demandez une traduction. Le modèle fait généralement un travail raisonnable avec le texte, mais traite les balises XLIFF de manière incohérente. Parfois, il préserve les balises <g>, parfois il traduit l'attribut id, parfois il les supprime entièrement. La validation échoue. Votre importation génère des erreurs d'analyse XML.
Utiliser un outil TAO sans support XLIFF
Des outils comme Poedit sont conçus pour le format .po. Ils peuvent ouvrir XLIFF mais le traitent comme un conteneur de texte générique. Les balises en ligne ne sont pas verrouillées. Les placeholders ne sont pas protégés. Vous obtenez une traduction qui semble correcte dans l'éditeur mais échoue à la validation du schéma lors de l'importation.
Écrire un script personnalisé
Votre équipe écrit un script Node ou Python qui analyse XLIFF avec xml2js, extrait les chaînes source, appelle Google Traduction et réécrit les cibles. Cela fonctionne pour 90 % des chaînes. Les 10 % restants – chaînes avec formatage imbriqué, groupes pluriels ou caractères spéciaux – se cassent d'une manière qui n'apparaît qu'après la mise en production.
Le même mode de défaillance « format flexible rencontre traducteur naïf » affecte les fichiers JSON i18next et les fichiers Gettext .po. Notre guide sur la traduction des fichiers JSON i18next pour React et Next.js et notre article sur comment traduire les fichiers .po sans casser les variables de code couvrent les problèmes parallèles pour ces formats.
La bonne méthode : Traitement XLIFF sensible à la syntaxe
Une chaîne de traduction XLIFF appropriée suit les mêmes principes que notre moteur PO, adapté pour XML.
Analyser, pas RegEx
Traitez XLIFF comme un document structuré. Analysez-le avec un véritable parseur XML, construisez un arbre et parcourez les éléments <trans-unit> (ou <unit> pour la version 2.0). Tenter de faire correspondre le contenu source et cible avec des expressions régulières est le moyen le plus rapide de corrompre les fichiers.
Verrouiller les balises en ligne avant la traduction
Chaque balise <g>, <x>, <bpt>, <ept>, <ph>, <pc> à l'intérieur d'une balise <source> doit être préservée par sa position et son attribut id. Remplacez-les par des placeholders numériques avant d'envoyer le texte au LLM, puis réinsérez les balises originales avec leurs attributs après le retour de la traduction.
Respecter la machine à états
Les unités XLIFF ont des attributs d'état : new, needs-translation, translated, reviewed, final, signed-off. Une chaîne de traitement ne devrait traduire que les unités dans les états new ou needs-translation, et définir l'état de sortie sur translated (pas final – un relecteur devrait toujours vérifier).
Préserver la structure au-delà des unités de traduction
Les fichiers XLIFF contiennent des en-têtes, des métadonnées, des attributs au niveau du fichier, des notes et des traductions alternatives (<alt-trans>). Ceux-ci doivent survivre inchangés pendant le cycle aller-retour. Les supprimer ou les réordonner rompt la compatibilité aller-retour avec la plateforme source.
Valider avant la livraison
Avant de renvoyer le fichier XLIFF traduit, validez-le par rapport au schéma. XLIFF 1.2 a un XSD officiel. XLIFF 2.0 a le sien. Un outil qui ne peut pas s'auto-valider est un outil qui vous livrera des fichiers corrompus.
Notes spécifiques à la plateforme
Chaque plateforme majeure utilisant XLIFF a des particularités à connaître.
Drupal
L'outil de gestion de traduction (TMGMT) de Drupal exporte XLIFF 1.2. Les types de contenu incluent les nœuds (pages, articles), les termes de taxonomie et la configuration. TMGMT enveloppe chaque champ traduisible dans une <trans-unit> séparée avec un format d'ID spécifique à Drupal (fieldname:delta:format).
Piège : Drupal stocke les informations de format de texte (HTML filtré, HTML complet, texte brut) à côté du contenu. La traduction doit préserver le balisage HTML lorsque le format le permet, et le réduire au texte brut lorsque le format ne le permet pas. Votre chaîne de traitement a besoin d'une conscience par champ.
Symfony
Le composant de traduction de Symfony utilise XLIFF 2.0 par défaut (depuis Symfony 4). Les chaînes se trouvent dans translations/messages.xx.xliff. Symfony prend en charge le format de message ICU à l'intérieur d'XLIFF, ce qui signifie qu'une seule unité peut contenir des structures {count, plural, one {...} other {...}}.
Piège : Les catégories de pluriels ICU à l'intérieur d'XLIFF nécessitent une double protection. Les balises XML restent intactes, ET les mots-clés ICU (plural, one, other, =0) ne doivent pas être traduits. De nombreux outils XLIFF gèrent une couche mais pas les deux.
Angular i18n
Angular exporte XLIFF 1.2 ou 2.0 via la commande ng extract-i18n. Les fichiers contiennent des chaînes de modèles de composants, avec des balises <x> représentant les expressions et interpolations Angular comme {{ count }}.
Piège : Angular utilise des collisions de hachage d'id pour des chaînes source identiques. Une traduction doit maintenir les ID d'unité exactement, sinon Angular ne peut pas les faire correspondre lors de l'importation. Renommer les attributs id pendant le traitement entraîne une rupture immédiate.
iOS (Exportation Xcode)
Xcode exporte XLIFF 1.2 pour la localisation d'applications via Product > Export Localizations. Les chaînes proviennent de Localizable.strings, des entrées Info.plist, des storyboards et des XIBs. Les règles de pluriel iOS se trouvent dans les fichiers .stringsdict exportés comme unités de traduction supplémentaires.
Piège : Les chaînes de storyboard iOS font référence aux ID d'éléments d'interface utilisateur. Celles-ci ne doivent pas être modifiées. De plus, Xcode exige que l'attribut target-language corresponde exactement à son format de locale attendu (es, et non es-ES, dans certains contextes) sinon il ignore silencieusement l'importation.
Traduire XLIFF avec SimplePoTranslate
SimplePoTranslate prend en charge XLIFF avec les forfaits Pro et Lifetime. Le flux de travail est le même que pour les fichiers .po.
1. Exportez votre XLIFF
Depuis votre plateforme source, exportez un ou plusieurs fichiers .xliff. Pour Drupal, utilisez l'action d'exportation de TMGMT. Pour Symfony, recherchez translations/messages.en.xliff. Pour Angular, exécutez ng extract-i18n --format=xlf2. Pour Xcode, utilisez l'exportation de localisation.
2. Téléchargez sur SimplePoTranslate
Faites glisser le fichier dans le tableau de bord. La plateforme détecte automatiquement la version XLIFF (1.2 ou 2.0), analyse la structure et identifie les unités traduisibles. Choisissez votre langue cible et votre ton.
3. Traduction sensible à la syntaxe
Les balises en ligne, les paramètres ICU, les placeholders et les ID d'unité sont verrouillés avant la traduction. Le moteur d'IA sous-jacent ne voit que du texte propre avec du contexte. Le texte traduit est réinséré dans la structure originale exacte, les états sont mis à jour et le fichier est validé par rapport au schéma XLIFF avant la livraison.
4. Téléchargez et importez
Téléchargez le fichier XLIFF traduit (ainsi que les équivalents .po, .json et .php si vous avez besoin d'une compatibilité multiplateforme). Importez-le dans votre plateforme source. Validez en affichant quelques pages ou vues traduites avant de déployer.
# Angular example
ng extract-i18n --format=xlf2 --output-path=src/locale
# upload src/locale/messages.xlf to SimplePoTranslate
# download messages.es.xlf
# reference in angular.json i18n configuration
ng build --localize
5. Intégrez à la CI
Une fois que vous faites confiance à la chaîne de traitement, automatisez-la. Exportez XLIFF à chaque version, soumettez via l'API, téléchargez les fichiers traduits, commitez-les au dépôt, déployez. C'est le même modèle compatible CI que de nombreuses agences utilisent pour la traduction .po de WordPress – consultez notre article sur la traduction basée sur le cloud sans sites cassés pour le modèle architectural.
Tout mettre en œuvre
XLIFF est l'outil idéal pour un travail de localisation sérieux – structuré, indépendant de l'outil et suffisamment riche pour transporter les métadonnées de projet entre les systèmes. Mais sa structure XML est également fragile. Chaque balise, attribut et valeur d'état a un poids sémantique, et un traducteur qui ne comprend pas XLIFF en tant que format corrompra votre fichier de manière qui pourrait ne pas apparaître avant que l'importation n'échoue ou qu'un utilisateur ne signale une interface utilisateur cassée.
L'approche sécurisée est sensible à la syntaxe : analysez le XML, verrouillez les éléments structurels, traduisez uniquement les surfaces de texte avec le contexte, validez par rapport au schéma avant la livraison. Cela est vrai que vous déployiez un site Drupal, une API Symfony, une SPA Angular ou une application iOS. La plateforme diffère, mais la discipline XLIFF ne change pas.
Prêt à traduire des fichiers XLIFF pour Drupal, Symfony, Angular ou iOS sans balises cassées ? Essayez SimplePoTranslate gratuitement – aucune carte de crédit requise. Téléchargez vos fichiers
.xliff, téléchargez des traductions sûres, importez-les dans votre plateforme.