기능플러그인가격리소스
언어 변경
리소스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를 손상시키는 이유, 그리고 XLIFF가 2026년에 가장 일반적으로 사용되는 네 가지 플랫폼인 Drupal, Symfony, Angular, iOS용 XLIFF 파일을 올바르게 번역하는 방법을 설명합니다.

XLIFF란 무엇인가 (그리고 기업 팀이 XLIFF를 사용하는 이유)

XLIFF는 XML Localization Interchange File Format의 약자입니다. 이는 콘텐츠 관리 시스템, 번역 메모리 데이터베이스, CAT 도구 및 로컬라이제이션 플랫폼과 같은 도구 간에 번역 콘텐츠를 이동하기 위해 특별히 설계된 OASIS 표준입니다. 플랫한 키-값 쌍을 저장하는 Gettext .po 파일이나 임의로 중첩될 수 있는 JSON 로케일 파일과는 달리, XLIFF는 표준화된 스키마를 가진 구조화된 XML 문서입니다.

XLIFF 1.2 vs XLIFF 2.0

두 가지 버전이 존재하며, 이들은 완전히 호환되지 않습니다.

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>

각각의 방식은 가져오기를 다르게 손상시킵니다. 첫 번째는 변수 이름을 바꿉니다. 두 번째는 XML을 이스케이프합니다. 세 번째는 서식 태그를 완전히 삭제합니다.

잘못된 해결책 (XML을 단순히 번역할 수 없는 이유)

대부분의 팀은 동일한 세 가지 접근 방식을 시도하며 며칠을 허비한 후 포기합니다.

XLIFF를 일반 AI에 제공하기

파일을 복사하여 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 단위는 new, needs-translation, translated, reviewed, final, signed-off와 같은 상태 속성을 가집니다. 파이프라인은 new 또는 needs-translation 상태의 단위만 번역해야 하며, 출력 상태를 translated로 설정해야 합니다 ( final 아님 – 검토자가 여전히 확인해야 합니다).

번역 단위를 넘어선 구조 보존

XLIFF 파일에는 헤더, 메타데이터, 파일 수준 속성, 메모 및 대체 번역 (<alt-trans>)이 포함됩니다. 이들은 왕복 과정에서 변경되지 않고 유지되어야 합니다. 이들을 제거하거나 재정렬하면 원본 플랫폼과의 왕복 호환성이 깨집니다.

전달 전 유효성 검사

번역된 XLIFF를 반환하기 전에 스키마에 대해 유효성 검사를 수행하세요. XLIFF 1.2에는 공식 XSD가 있습니다. XLIFF 2.0에는 자체 스키마가 있습니다. 자체 유효성 검사를 할 수 없는 도구는 손상된 파일을 전달할 것입니다.

플랫폼별 참고 사항

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 메시지 형식을 지원하며, 이는 단일 단위가 {count, plural, one {...} other {...}} 구조를 포함할 수 있음을 의미합니다.

주의할 점: XLIFF 내의 ICU 복수 범주는 이중 보호가 필요합니다. XML 태그는 그대로 유지되어야 하며, ICU 키워드 (plural, one, other, =0)는 번역되지 않아야 합니다. 많은 XLIFF 도구는 한 가지 계층만 처리하고 두 가지 모두를 처리하지 못합니다.

Angular i18n

Angular는 ng extract-i18n 명령을 통해 XLIFF 1.2 또는 2.0을 내보냅니다. 파일에는 <x> 태그가 Angular 표현식 및 {{ count }}와 같은 보간을 나타내는 컴포넌트 템플릿 문자열이 포함됩니다.

주의할 점: 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 내보내기

원본 플랫폼에서 하나 이상의 .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를 업로드하고, 안전한 번역을 다운로드하여 플랫폼으로 가져오세요.