This package provides a MessageSource for using translations from XLIFF files. The package support XLIFF versions 1.2, 2.0 and 2.1.
<dependency>
<groupId>io.github.alaugks</groupId>
<artifactId>spring-messagesource-xliff</artifactId>
<version>2.0.0</version>
</dependency>
implementation group: 'io.github.alaugks', name: 'spring-messagesource-xliff', version: '2.0.0'
builder(Locale defaultLocale, String locationPattern)
or
builder(Locale defaultLocale, List<String> locationPatterns)
(required)
- Argument
Locale locale
: Defines the default locale. - Argument
String locationPattern
|List<String> locationPatterns
:- Defines the pattern used to select the XLIFF files.
- The package uses the PathMatchingResourcePatternResolver to select the XLIFF files. So you can use the supported patterns.
- Files with the extension
xliff
andxlf
are filtered from the result list.
defaultDomain(String defaultDomain)
- Defines the default domain. Default is
messages
. For more information, see XLIFF Files.
- Default locale is
en
. - The XLIFF files are stored in
src/main/resources/translations
.
import io.github.alaugks.spring.messagesource.xliff.XliffResourceMessageSource;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Locale;
@Configuration
public class MessageSourceConfig {
@Bean
public MessageSource messageSource() {
return XliffResourceMessageSource
.builder(
Locale.forLanguageTag("en"),
"translations/*"
)
.build();
}
}
- Translations can be separated into different files (domains). The default domain is
messages
. - The default domain can be defined.
- Translation files must be stored in the resource folder and have the extension
xliff
orxlf
. - In the XLIFF files, the
<target/>
is retrieved in a<trans-unit/>
(XLIFF 1.2) or<segment/>
(XLIFF 2.*).- XLIFF 1.2:
- If the attribute
resname
does not exist, the attributeid
is used to determine the identifier. - Documentation identifier: XLIFF 1.2
- If the attribute
- XLIFF 2.*:
- XLIFF 1.2:
- All attributes in the
<file/>
tag are ignored. - For performance reasons, there is no validation of XLIFF files with an XMLSchema.
- SAX parser errors are handled by an ErrorHandler.
# Default language
<domain>.xlf // <domain>_<language>.xlf also works.
# Domain + Language
<domain>[-_]<language>.xlf
# Domain + Language + Region
<domain>[-_]<language>[-_]<region>.xlf
- Default domain is
messages
. - Default locale is
en
without region. - Translations are provided for the locale
en
,de
anden-US
.
[resources]
|-[translations]
|-messages.xliff // Default domain and default language. messages_en.xliff also works.
|-messages_de.xliff
|-messages_en-US.xliff
|-payment.xliff // Default language. payment_en.xliff also works.
|-payment_de.xliff
|-payment_en-US.xliff
Mixing XLIFF versions is possible. Here is an example using XLIFF 1.2 and XLIFF 2.1.
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2"
xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en"
target-language="en">
<body>
<trans-unit id="headline">
<source>Headline</source>
<target>Headline</target>
</trans-unit>
<trans-unit id="postcode">
<source>Postcode</source>
<target>Postcode</target>
</trans-unit>
</body>
</file>
</xliff>
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2"
xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en"
target-language="de">
<body>
<trans-unit id="headline">
<source>Headline</source>
<target>Überschrift</target>
</trans-unit>
<trans-unit id="postcode">
<source>Postcode</source>
<target>Postleitzahl</target>
</trans-unit>
</body>
</file>
</xliff>
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2"
xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en"
target-language="en-US">
<body>
<trans-unit id="postcode">
<source>Postcode</source>
<target>Zip code</target>
</trans-unit>
</body>
</file>
</xliff>
<?xml version="1.0" encoding="UTF-8" ?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:2.1" version="2.1"
srcLang="en" trgLang="en">
<file id="payment">
<unit>
<segment id="headline">
<source>Payment</source>
<target>Payment</target>
</segment>
<segment id="expiry_date">
<source>Expiry date</source>
<target>Expiry date</target>
</segment>
</unit>
</file>
</xliff>
<?xml version="1.0" encoding="UTF-8" ?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:2.1" version="2.1"
srcLang="en" trgLang="de">
<file id="payment_de">
<unit>
<segment id="headline">
<source>Payment</source>
<target>Zahlung</target>
</segment>
<segment id="expiry_date">
<source>Expiry date</source>
<target>Ablaufdatum</target>
</segment>
</unit>
</file>
</xliff>
<?xml version="1.0" encoding="UTF-8" ?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:2.1" version="2.1"
srcLang="en" trgLang="en-US">
<file id="payment_en-US">
<unit>
<segment id="expiry_date">
<source>Expiry date</source>
<target>Expiration date</target>
</segment>
</unit>
</file>
</xliff>
The behaviour of resolving the target value based on the code is equivalent to the ResourceBundleMessageSource or ReloadableResourceBundleMessageSource.
id (code) | en | en-US | de | jp*** |
---|---|---|---|---|
headline* messages.headline |
Headline | Headline** | Überschrift | Headline |
postcode* messages.postcode |
Postcode | Zip code | Postleitzahl | Postcode |
payment.headline | Payment | Payment** | Zahlung | Payment |
payment.expiry_date | Expiry date | Expiration date | Ablaufdatum | Expiry date |
*Default domain is
messages
.**Example of a fallback from Language_Region (
en-US
) to Language (en
). Theid
does not exist inen-US
, so it tries to select the translation with localeen
.***There is no translation for Japanese (
jp
). The default locale translations (en
) are selected.
A Full Example using Spring Boot, mixing XLIFF 1.2 and XLIFF 2.1 translation files:
Repository: https://github.com/alaugks/spring-messagesource-xliff-example
Website: https://spring-boot-xliff-example.alaugks.dev
If you have questions, comments or feature requests please use the Discussions section.