{"id":19893077,"url":"https://github.com/alaugks/spring-messagesource-xliff","last_synced_at":"2025-09-16T12:58:19.165Z","repository":{"id":175603988,"uuid":"652638808","full_name":"alaugks/spring-messagesource-xliff","owner":"alaugks","description":"This package provides a MessageSource for using translations from XLIFF files. The package support XLIFF versions 1.2, 2.0 and 2.1.","archived":false,"fork":false,"pushed_at":"2024-04-10T17:10:32.000Z","size":165,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-04-11T12:27:20.120Z","etag":null,"topics":["i18n","internationalization","messagesource","spring","spring-boot","spring-messagesource-xliff","spring-translation-xliff","thymeleaf","translation","xliff","xliff-files","xliff2"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alaugks.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2023-06-12T13:40:48.000Z","updated_at":"2024-04-14T17:55:56.489Z","dependencies_parsed_at":null,"dependency_job_id":"f61e7ef7-aa44-416e-a5d1-2cf1084afc23","html_url":"https://github.com/alaugks/spring-messagesource-xliff","commit_stats":null,"previous_names":["alaugks/spring-xliff-translation","alaugks/spring-messagesource-xliff"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alaugks%2Fspring-messagesource-xliff","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alaugks%2Fspring-messagesource-xliff/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alaugks%2Fspring-messagesource-xliff/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alaugks%2Fspring-messagesource-xliff/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alaugks","download_url":"https://codeload.github.com/alaugks/spring-messagesource-xliff/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241321880,"owners_count":19944037,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["i18n","internationalization","messagesource","spring","spring-boot","spring-messagesource-xliff","spring-translation-xliff","thymeleaf","translation","xliff","xliff-files","xliff2"],"created_at":"2024-11-12T18:27:19.869Z","updated_at":"2025-09-16T12:58:19.158Z","avatar_url":"https://github.com/alaugks.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# XLIFF MessageSource for Spring\n\nThis package provides a [MessageSource](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/MessageSource.html) for using translations from XLIFF files. The package support XLIFF versions 1.2, 2.0 and 2.1.\n\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=alaugks_spring-xliff-translation\u0026metric=alert_status)](https://sonarcloud.io/summary/overall?id=alaugks_spring-xliff-translation)\n[![Maven Central](https://img.shields.io/maven-central/v/io.github.alaugks/spring-messagesource-xliff.svg?label=Maven%20Central)](https://central.sonatype.com/artifact/io.github.alaugks/spring-messagesource-xliff/2.0.0)\n\n## Dependency\n\n### Maven\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.github.alaugks\u003c/groupId\u003e\n    \u003cartifactId\u003espring-messagesource-xliff\u003c/artifactId\u003e\n    \u003cversion\u003e2.0.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### Gradle \n\n```text\nimplementation group: 'io.github.alaugks', name: 'spring-messagesource-xliff', version: '2.0.0'\n```\n\n\n## MessageSource Configuration\n\n`builder(Locale defaultLocale, String locationPattern)` or\u003cbr\u003e\n`builder(Locale defaultLocale, List\u003cString\u003e locationPatterns)` (***required***)\n* Argument `Locale locale`: Defines the default locale.\n* Argument `String locationPattern` | `List\u003cString\u003e locationPatterns`:\n  * Defines the pattern used to select the XLIFF files.\n  * The package uses the [PathMatchingResourcePatternResolver](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/io/support/PathMatchingResourcePatternResolver.html) to select the XLIFF files. So you can use the supported patterns.\n  * Files with the extension `xliff` and `xlf` are filtered from the result list.\n\n`defaultDomain(String defaultDomain)`\n\n* Defines the default domain. Default is `messages`. For more information, see [XLIFF Files](#xliff-files).\n\n\n### Example\n\n* Default locale is `en`.\n* The XLIFF files are stored in `src/main/resources/translations`.\n\n```java\nimport io.github.alaugks.spring.messagesource.xliff.XliffResourceMessageSource;\nimport org.springframework.context.MessageSource;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport java.util.Locale;\n\n@Configuration\npublic class MessageSourceConfig {\n\n    @Bean\n    public MessageSource messageSource() {\n       return XliffResourceMessageSource\n               .builder(\n                   Locale.forLanguageTag(\"en\"),\n                   \"translations/*\"\n               )\n               .build();\n    }\n\n}\n```\n\n## XLIFF Files\n\n* Translations can be separated into different files (domains). The default domain is `messages`.\n* The default domain can be defined.\n* Translation files must be stored in the resource folder and have the extension `xliff` or `xlf`.\n* In the XLIFF files, the `\u003ctarget/\u003e` is retrieved in a `\u003ctrans-unit/\u003e` (XLIFF 1.2) or `\u003csegment/\u003e` (XLIFF 2.*).\n  * **XLIFF 1.2**:\n    * If the attribute `resname` does not exist, the attribute `id` is used to determine the identifier.\n    * Documentation identifier: [XLIFF 1.2](http://docs.oasis-open.org/xliff/v1.2/xliff-profile-html/xliff-profile-html-1.2.html#General_Identifiers)\n  * **XLIFF 2.\u0026ast;**:\n    * The attribute `id` is optional by standard in XLIFF 2.*. However, this package requires the `id` on a translation unit.\n    * Documentation identifier: [XLIFF 2.0](https://docs.oasis-open.org/xliff/xliff-core/v2.0/csprd01/xliff-core-v2.0-csprd01.html#segment) and [XLIFF 2.1](https://docs.oasis-open.org/xliff/xliff-core/v2.1/os/xliff-core-v2.1-os.html#segment)\n* All attributes in the `\u003cfile/\u003e` tag are ignored.  \n* For performance reasons, there is no validation of XLIFF files with an XMLSchema.\n* SAX parser errors are handled by an [ErrorHandler](src/main/java/io/github/alaugks/spring/messagesource/xliff/exception/SaxErrorHandler.java).\n\n### Structure of the Translation Filename\n\n```\n# Default language\n\u003cdomain\u003e.xlf    // \u003cdomain\u003e_\u003clanguage\u003e.xlf also works.\n\n# Domain + Language\n\u003cdomain\u003e[-_]\u003clanguage\u003e.xlf\n\n# Domain + Language + Region\n\u003cdomain\u003e[-_]\u003clanguage\u003e[-_]\u003cregion\u003e.xlf\n```\n\n### Example with XLIFF Files\n\n* Default domain is `messages`.\n* Default locale is `en` without region.\n* Translations are provided for the locale `en`, `de` and `en-US`.\n\n```\n[resources]\n     |-[translations]\n             |-messages.xliff           // Default domain and default language. messages_en.xliff also works.\n             |-messages_de.xliff\n             |-messages_en-US.xliff\n             |-payment.xliff            // Default language. payment_en.xliff also works.\n             |-payment_de.xliff\n             |-payment_en-US.xliff     \n```  \n\n#### XLIFF Files\n\nMixing XLIFF versions is possible. Here is an example using XLIFF 1.2 and XLIFF 2.1.\n\n##### messages.xliff\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003cxliff version=\"1.2\"\n       xmlns=\"urn:oasis:names:tc:xliff:document:1.2\"\u003e\n    \u003cfile source-language=\"en\"\n          target-language=\"en\"\u003e\n        \u003cbody\u003e\n            \u003ctrans-unit id=\"headline\"\u003e\n                \u003csource\u003eHeadline\u003c/source\u003e\n                \u003ctarget\u003eHeadline\u003c/target\u003e\n            \u003c/trans-unit\u003e\n            \u003ctrans-unit id=\"postcode\"\u003e\n                \u003csource\u003ePostcode\u003c/source\u003e\n                \u003ctarget\u003ePostcode\u003c/target\u003e\n            \u003c/trans-unit\u003e\n        \u003c/body\u003e\n    \u003c/file\u003e\n\u003c/xliff\u003e\n```\n\n##### messages_de.xliff\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003cxliff version=\"1.2\"\n       xmlns=\"urn:oasis:names:tc:xliff:document:1.2\"\u003e\n    \u003cfile source-language=\"en\"\n          target-language=\"de\"\u003e\n        \u003cbody\u003e\n            \u003ctrans-unit id=\"headline\"\u003e\n                \u003csource\u003eHeadline\u003c/source\u003e\n                \u003ctarget\u003eÜberschrift\u003c/target\u003e\n            \u003c/trans-unit\u003e\n            \u003ctrans-unit id=\"postcode\"\u003e\n                \u003csource\u003ePostcode\u003c/source\u003e\n                \u003ctarget\u003ePostleitzahl\u003c/target\u003e\n            \u003c/trans-unit\u003e\n        \u003c/body\u003e\n    \u003c/file\u003e\n\u003c/xliff\u003e\n```\n\n##### messages_en-US.xliff\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003cxliff version=\"1.2\"\n       xmlns=\"urn:oasis:names:tc:xliff:document:1.2\"\u003e\n    \u003cfile source-language=\"en\"\n          target-language=\"en-US\"\u003e\n        \u003cbody\u003e\n            \u003ctrans-unit id=\"postcode\"\u003e\n                \u003csource\u003ePostcode\u003c/source\u003e\n                \u003ctarget\u003eZip code\u003c/target\u003e\n            \u003c/trans-unit\u003e\n        \u003c/body\u003e\n    \u003c/file\u003e\n\u003c/xliff\u003e\n```\n\n##### payment.xliff\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\" ?\u003e\n\u003cxliff xmlns=\"urn:oasis:names:tc:xliff:document:2.1\" version=\"2.1\"\n       srcLang=\"en\" trgLang=\"en\"\u003e\n    \u003cfile id=\"payment\"\u003e\n        \u003cunit\u003e\n            \u003csegment id=\"headline\"\u003e\n                \u003csource\u003ePayment\u003c/source\u003e\n                \u003ctarget\u003ePayment\u003c/target\u003e\n            \u003c/segment\u003e\n            \u003csegment id=\"expiry_date\"\u003e\n                \u003csource\u003eExpiry date\u003c/source\u003e\n                \u003ctarget\u003eExpiry date\u003c/target\u003e\n            \u003c/segment\u003e\n        \u003c/unit\u003e\n    \u003c/file\u003e\n\u003c/xliff\u003e\n```\n\n##### payment_de.xliff\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\" ?\u003e\n\u003cxliff xmlns=\"urn:oasis:names:tc:xliff:document:2.1\" version=\"2.1\"\n       srcLang=\"en\" trgLang=\"de\"\u003e\n    \u003cfile id=\"payment_de\"\u003e\n        \u003cunit\u003e\n            \u003csegment id=\"headline\"\u003e\n                \u003csource\u003ePayment\u003c/source\u003e\n                \u003ctarget\u003eZahlung\u003c/target\u003e\n            \u003c/segment\u003e\n            \u003csegment id=\"expiry_date\"\u003e\n                \u003csource\u003eExpiry date\u003c/source\u003e\n                \u003ctarget\u003eAblaufdatum\u003c/target\u003e\n            \u003c/segment\u003e\n        \u003c/unit\u003e\n    \u003c/file\u003e\n\u003c/xliff\u003e\n```\n\n##### payment_en-US.xliff\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\" ?\u003e\n\u003cxliff xmlns=\"urn:oasis:names:tc:xliff:document:2.1\" version=\"2.1\"\n       srcLang=\"en\" trgLang=\"en-US\"\u003e\n    \u003cfile id=\"payment_en-US\"\u003e\n        \u003cunit\u003e\n            \u003csegment id=\"expiry_date\"\u003e\n                \u003csource\u003eExpiry date\u003c/source\u003e\n                \u003ctarget\u003eExpiration date\u003c/target\u003e\n            \u003c/segment\u003e\n        \u003c/unit\u003e\n    \u003c/file\u003e\n\u003c/xliff\u003e\n```\n\n#### Target value\n\nThe behaviour of resolving the target value based on the code is equivalent to the ResourceBundleMessageSource or ReloadableResourceBundleMessageSource.\n\n\u003ctable\u003e\n  \u003cthead\u003e\n  \u003ctr\u003e\n    \u003cth\u003eid (code)\u003c/th\u003e\n    \u003cth\u003een\u003c/th\u003e\n    \u003cth\u003een-US\u003c/th\u003e\n    \u003cth\u003ede\u003c/th\u003e\n    \u003cth\u003ejp***\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eheadline*\u003cbr\u003emessages.headline\u003c/td\u003e\n    \u003ctd\u003eHeadline\u003c/td\u003e\n    \u003ctd\u003eHeadline**\u003c/td\u003e\n    \u003ctd\u003eÜberschrift\u003c/td\u003e\n    \u003ctd\u003eHeadline\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003epostcode*\u003cbr\u003emessages.postcode\u003c/td\u003e\n    \u003ctd\u003ePostcode\u003c/td\u003e\n    \u003ctd\u003eZip code\u003c/td\u003e\n    \u003ctd\u003ePostleitzahl\u003c/td\u003e\n    \u003ctd\u003ePostcode\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003epayment.headline\u003c/td\u003e\n    \u003ctd\u003ePayment\u003c/td\u003e\n    \u003ctd\u003ePayment**\u003c/td\u003e\n    \u003ctd\u003eZahlung\u003c/td\u003e\n    \u003ctd\u003ePayment\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003epayment.expiry_date\u003c/td\u003e\n    \u003ctd\u003eExpiry date\u003c/td\u003e\n    \u003ctd\u003eExpiration date\u003c/td\u003e\n    \u003ctd\u003eAblaufdatum\u003c/td\u003e\n    \u003ctd\u003eExpiry date\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003e *Default domain is `messages`.\n\u003e\n\u003e **Example of a fallback from Language_Region (`en-US`) to Language (`en`). The `id` does not exist in `en-US`, so it tries to select the translation with locale `en`.\n\u003e \n\u003e ***There is no translation for Japanese (`jp`). The default locale translations (`en`) are selected.\n\n## Full Example\n\nA Full Example using Spring Boot, mixing XLIFF 1.2 and XLIFF 2.1 translation files:\n\nRepository: https://github.com/alaugks/spring-messagesource-xliff-example\u003cbr\u003e\nWebsite: https://spring-boot-xliff-example.alaugks.dev\n\n## Support\n\nIf you have questions, comments or feature requests please use the [Discussions](https://github.com/alaugks/spring-xliff-translation/discussions) section.\n\n\n## Related MessageSources and Examples\n\n* [JSON MessageSource for Spring](https://github.com/alaugks/spring-messagesource-json)\n* [Example: JSON MessageSource for Spring](https://github.com/alaugks/spring-messagesource-json-example)\n* [Example: Custom Database Spring MessageSource](https://github.com/alaugks/spring-messagesource-db-example)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falaugks%2Fspring-messagesource-xliff","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falaugks%2Fspring-messagesource-xliff","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falaugks%2Fspring-messagesource-xliff/lists"}