機能プラグイン料金リソース
言語を変更
リソースXLIFFファイル(Drupal、Symfony、Angular、iOS)を翻訳する方法

XLIFFファイル(Drupal、Symfony、Angular、iOS)を翻訳する方法

SimplePoTranslate Team2026年4月16日
XLIFFファイル(Drupal、Symfony、Angular、iOS)を翻訳する方法

先週、Drupal開発者がStack Overflowに投稿した話は、企業ローカライゼーションチームで毎年何千回と繰り返される状況です。彼女のチームはDrupalサイトから40MBのXLIFFファイルをエクスポートしました。それをテキストエディタで開き、一部をGoogle Translateに貼り付け、ファイルを再構築してDrupalにインポートし直したところ、翻訳された文字列に不正なXML、間違った位置のエスケープ文字、インラインフォーマットが破壊された壊れた<g>タグが含まれていたため、ページの半分がレンダリングされませんでした。

XLIFFが企業ローカライゼーションの標準であるのには理由があります。XMLベースで、ツールに依存せず、本格的な翻訳プロジェクトに必要な豊富なメタデータ(翻訳状態、代替翻訳、翻訳者と開発者間のメモ、構造化されたインラインマークアップなど)をサポートします。しかし、その柔軟性ゆえに簡単に破損しやすく、.poファイルを安全に処理するツールでもXLIFFでは機能しないことがよくあります。

このガイドでは、XLIFFの特徴、一般的な翻訳アプローチがそれを破損させる理由、そしてXLIFFが2026年に最も一般的に使用される4つのプラットフォームであるDrupal、Symfony、Angular、iOS向けにXLIFFファイルを翻訳する正しい方法について解説します。

XLIFFとは何か(そしてなぜ企業チームがそれを使うのか)

XLIFFはXML Localization Interchange File Formatの略です。これは、コンテンツ管理システム、翻訳メモリデータベース、CATツール、ローカライゼーションプラットフォームなど、ツール間で翻訳コンテンツを移動するために特別に設計されたOASIS標準です。Gettextの.poファイル(フラットなキーと値のペアを保存)やJSONロケールファイル(任意にネストする)とは異なり、XLIFFは標準化されたスキーマを持つ構造化されたXMLドキュメントです。

XLIFF 1.2 vs XLIFF 2.0

2つのバージョンが存在し、それらは完全に互換性がありません。

XLIFF 1.2は、より古く、広く普及しているバージョンです。翻訳可能なコンテンツを<trans-unit>要素で囲み、その子要素として<source><target>を使用します。インラインフォーマットには<g><x>、そして<bpt> / <ept>のペアタグを使用します。DrupalのTranslation Management Toolや多くの古いプラットフォームは現在も1.2をエクスポートしています。

XLIFF 2.0は、2014年の改訂版で、よりシンプルでクリーンです。<unit><segment><source><target>とともに使用します。インラインマークアップには<pc>(ペアコード)と<ph>(プレースホルダー)を使用します。Symfonyの翻訳コンポーネントや最新のiOSのエクスポートはデフォルトで2.0です。

1.2を扱う翻訳ツールが自動的に2.0を扱うわけではありません。タグの語彙が異なり、エスケープルールもわずかに異なります。翻訳パイプラインを選択する前に、プラットフォームがどのバージョンをエクスポートするかを常に確認してください。

XLIFFユニットの構造

最小限のXLIFF 1.2のtrans-unitは次のようになります。

<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>

<g id="1">はプレースホルダー変数を囲んでいます。state属性は、この文字列が翻訳を必要とすることを示します。<note>は開発者へのヒントです。XLIFFを理解している翻訳者は、次のように作成するはずです。

<target state="translated">¡Bienvenido, <g id="1">%name%</g>!</target>

ファイルをプレーンテキストとして扱う翻訳者は、次のようないずれかの壊れたバリアントを作成する可能性があります。

<target>¡Bienvenido, <g id="1">%nombre%</g>!</target>
<target>¡Bienvenido, &lt;g id="1"&gt;%name%&lt;/g&gt;!</target>
<target>¡Bienvenido, %name%!</target>

これらのそれぞれが異なる方法でインポートを破壊します。最初のものは変数をリネームし、2番目のものはXMLをエスケープし、3番目のものはフォーマットタグを完全に削除しています。

悪い解決策(XMLをそのまま翻訳できない理由)

ほとんどのチームは同じ3つのアプローチから始め、数日を費やした後に諦めます。

汎用AIにXLIFFを投入する

ファイルをコピーし、ClaudeやChatGPTに貼り付けて翻訳を依頼します。モデルは通常、テキストについては適切に処理しますが、XLIFFタグの一貫性に欠けます。<g>タグを保持する場合もあれば、id属性を翻訳する場合、あるいは完全に削除する場合もあります。検証に失敗し、インポート時にXML解析エラーが発生します。

XLIFFをサポートしないCATツールを使用する

Poeditのようなツールは.po形式のために作られています。XLIFFを開くことはできますが、一般的なテキストコンテナとして扱われます。インラインタグはロックされず、プレースホルダーは保護されません。エディタでは問題なく見える翻訳が得られますが、インポート時にスキーマ検証に失敗します。

カスタムスクリプトの作成

あなたのチームは、xml2jsでXLIFFを解析し、ソース文字列を抽出し、Google Translateを呼び出し、ターゲットを書き戻すNodeまたはPythonスクリプトを作成します。これは文字列の90%には機能します。残りの10%(ネストされた書式設定、複数形グループ、特殊文字を持つ文字列)は、既にデプロイした後になって初めて現れる方法で破損します。

同じ「柔軟なフォーマットと素朴な翻訳者のミスマッチ」という失敗パターンは、i18next JSONファイルやGettextの.poファイルにも影響します。ReactおよびNext.js向けのi18next JSONファイルを翻訳する方法に関するガイドと、コード変数を壊さずに.poファイルを翻訳する方法に関する投稿では、これらのフォーマットにおける同様の問題を扱っています。

正しい方法:構文を認識したXLIFF処理

適切なXLIFF翻訳パイプラインは、XML向けに調整された当社のPOエンジンと同じ原則に従います。

パースする、正規表現ではない

XLIFFを構造化されたドキュメントとして扱います。実際のXMLパーサーで解析し、ツリーを構築し、<trans-unit>(2.0の場合は<unit>)要素をたどります。ソースとターゲットのコンテンツを正規表現でマッチさせようとすると、ファイル破損への速い道筋となります。

翻訳前にインラインタグをロックする

<source>内のすべての<g><x><bpt><ept><ph><pc>は、位置とid属性によって保持されなければなりません。テキストをLLMに送信する前にそれらを数値プレースホルダーに置き換え、翻訳が返された後に元のタグとその属性を再挿入します。

ステートマシンを尊重する

XLIFFユニットには、newneeds-translationtranslatedreviewedfinalsigned-offといった状態属性があります。パイプラインはnewまたはneeds-translation状態のユニットのみを翻訳し、出力状態をtranslatedに設定するべきです(finalではない - レビュー担当者がまだ検証する必要があります)。

翻訳ユニット以外の構造を保持する

XLIFFファイルには、ヘッダー、メタデータ、ファイルレベルの属性、メモ、および代替翻訳(<alt-trans>)が含まれています。これらはラウンドトリップを通じて変更されずに保持されなければなりません。これらを削除したり順序を変更したりすると、ソースプラットフォームとのラウンドトリップ互換性が損なわれます。

配信前に検証する

翻訳されたXLIFFを返す前に、スキーマに対して検証します。XLIFF 1.2には公式のXSDがあり、XLIFF 2.0には独自のXSDがあります。自己検証できないツールは、破損したファイルをあなたに届けることになります。

プラットフォーム固有の注意事項

XLIFFを使用する主要なプラットフォームには、知っておくべき癖があります。

Drupal

DrupalのTranslation Management Tool (TMGMT) はXLIFF 1.2をエクスポートします。コンテンツタイプには、ノード(ページ、記事)、タクソノミー用語、および設定が含まれます。TMGMTは、各翻訳可能なフィールドをDrupal固有のID形式(fieldname:delta:format)を持つ個別の<trans-unit>で囲みます。

注意点:Drupalは、テキスト形式情報(フィルタ済みHTML、フルHTML、プレーンテキスト)をコンテンツと共に保存します。翻訳では、形式が許す場合はHTMLマークアップを保持し、許さない場合はプレーンテキストに変換する必要があります。あなたのパイプラインはフィールドごとの認識を必要とします。

Symfony

Symfonyの翻訳コンポーネントは、デフォルトでXLIFF 2.0を使用します(Symfony 4以降)。文字列はtranslations/messages.xx.xliffに格納されます。SymfonyはXLIFF内でICUメッセージ形式をサポートしており、これは1つのユニットが{count, plural, one {...} other {...}}のような構造を含むことができることを意味します。

注意点:XLIFF内のICU複数形カテゴリは二重の保護が必要です。XMLタグはそのまま維持され、さらにICUキーワード(pluraloneother=0)は翻訳されてはなりません。多くのXLIFFツールは一方の層は処理しますが、両方は処理しません。

Angular i18n

Angularはng extract-i18nコマンドを通じてXLIFF 1.2または2.0をエクスポートします。ファイルにはコンポーネントテンプレート文字列が含まれ、Angularの式や{{ count }}のような補間を<x>タグで表現します。

注意点:Angularは、同一のソース文字列間でidハッシュの衝突を使用します。翻訳ではユニットIDを正確に維持する必要があり、そうしないとAngularはインポート時にそれらを一致させることができません。処理中にid属性の名前を変更すると、即座に破損します。

iOS (Xcodeエクスポート)

XcodeはProduct > Export Localizationsを通じて、アプリのローカライゼーション用にXLIFF 1.2をエクスポートします。文字列はLocalizable.strings、Info.plistエントリ、ストーリーボード、XIBから取得されます。iOSの複数形ルールは、追加のtrans-unitとしてエクスポートされる.stringsdictファイルに格納されています。

注意点:iOSのストーリーボード文字列はUI要素IDを参照します。これらは変更してはなりません。また、Xcodeはtarget-language属性が期待されるロケール形式(一部のコンテキストではes-ESではなくes)と完全に一致することを要求し、そうでない場合、インポートをサイレントに無視します。

SimplePoTranslateでXLIFFを翻訳する

SimplePoTranslateはProおよびLifetimeプランでXLIFFをサポートしています。ワークフローは.poファイルと同じです。

1. XLIFFをエクスポートする

ソースプラットフォームから、1つ以上の.xliffファイルをエクスポートします。Drupalの場合はTMGMTのエクスポートアクションを使用します。Symfonyの場合はtranslations/messages.en.xliffを見つけます。Angularの場合はng extract-i18n --format=xlf2を実行します。Xcodeの場合はローカライゼーションエクスポートを使用します。

2. SimplePoTranslateにアップロードする

ファイルをダッシュボードにドラッグします。プラットフォームはXLIFFバージョン(1.2または2.0)を自動検出し、構造を解析し、翻訳可能なユニットを特定します。ターゲット言語とトーンを選択します。

3. 構文を認識した翻訳

インラインタグ、ICUパラメータ、プレースホルダー、ユニットIDは翻訳前にロックされます。基盤となるAIエンジンは、コンテキストを持つクリーンなテキストのみを認識します。翻訳されたテキストは元の正確な構造に再挿入され、状態が更新され、配信前にXLIFFスキーマに対してファイルが検証されます。

4. ダウンロードとインポート

翻訳されたXLIFF(クロスプラットフォームが必要な場合は、.po.json、および.phpの同等ファイルも)をダウンロードします。ソースプラットフォームにインポートします。展開する前に、いくつかの翻訳されたページまたはビューをレンダリングして検証します。

# 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. CIに統合する

パイプラインを信頼できるようになったら、自動化します。リリースごとにXLIFFをエクスポートし、API経由で送信し、翻訳ファイルをダウンロードし、リポジトリにコミットし、デプロイします。これは、多くの代理店がWordPressの.po翻訳に使用しているCIフレンドリーなパターンと同じです。そのアーキテクチャパターンについては、サイトを壊さないクラウドベースの翻訳に関する弊社の投稿を参照してください。

まとめ

XLIFFは、本格的なローカライゼーション作業に適したツールです。構造化されており、ツールに依存せず、システム間でプロジェクトのメタデータを運ぶのに十分なほど豊富です。しかし、そのXML構造は脆いものでもあります。すべてのタグ、属性、状態値には意味的な重みがあり、XLIFFをフォーマットとして理解していない翻訳者は、インポートが失敗したり、ユーザーがUIの破損を報告したりするまで表面化しない形でファイルを破損させる可能性があります。

安全なアプローチは、構文を認識することです。XMLを解析し、構造要素をロックし、コンテキストを持つテキスト表面のみを翻訳し、配信前にスキーマに対して検証します。これは、Drupalサイト、Symfony API、Angular SPA、またはiOSアプリのいずれを出荷する場合でも当てはまります。プラットフォームは異なりますが、XLIFFの規律は変わりません。

Drupal、Symfony、Angular、iOS向けのXLIFFファイルをタグを壊さずに翻訳する準備はできましたか?SimplePoTranslateを無料で試す - クレジットカードは不要です。.xliffをアップロードし、安全な翻訳をダウンロードして、お使いのプラットフォームにインポートしてください。