Friday, July 23, 2010

Moving your XLIFF Files

The XML translation files generated from Oracle Application Express are produced in XML Localization Interchange File Format (XLIFF) format. XLIFF is a recognized standard for the localization of computer software. "It is intended to give any software provider a single interchange file format that can be understood by any localization provider."

One of the unique characteristics of Application Express is that it is one of the few development frameworks where the decision to localize and translate an application can be made after the application is actually completed. Because the definition of the application is maintained in meta data in the APEX repository, it's already known in advance which attributes of your application are translatable and which are not.

The process to produce a translated application is pretty straightforward. It's as simple as:

  1. Seed the translation repository from your existing application
  2. Export the XLIFF file
  3. Translate the XLIFF file
  4. Upload the XLIFF file
  5. Apply the XLIFF file
  6. Publish your translated application

The first few translation unit lines of a sample XLIFF file generated from Application Express look like:



Logout
Logout


Print
Print


Logout
Logout


Print
Print


Home
Home


Customers
Customers


Products
Products


Orders
Orders


Charts
Charts




Each translatable string is included as a 'trans-unit' in the XLIFF file. The last two elements of each translation unit ID are the meta data ID and the application ID. For example, in translation unit with id S-4-885632445599895776-25721, the meta data ID is 885632445599895776 and the application ID is 25721. (S-4 is an internal code signifying that this is a meta data string and corresponds to the text of a tab).

As I've discussed in a recent blog post about saved Interactive Reports, I explained how the internal meta data IDs "shift" or are recalculated when importing an application to a new ID. And this has presented problems for those customers who make use of the translation facilities of Application Express. Because the meta data IDs are a part of the XLIFF translation unit IDs, when those IDs change, the existing XLIFF files for the original application cannot be used against a new version of the application imported elsewhere as a new application ID. What a dead end!

I have authored an APEX application which helps customers overcome this problem. You can run the hosted version of the XLIFF Transformation application which is running in my workspace on apex.oracle.com, or you can download a copy of it and run it on your own APEX 4.0 or later instance. You need to provide 3 things when running this application:

  1. The original XLIFF file
  2. The application ID of the new application
  3. The offset value between the two applications

To compute #3, I'll refer you to this same blog post where I give a couple examples how to determine the offset value.

The logic is really quite simple. After importing the application and installing the supporting objects, only 3 objects will be created - a table named XLIFF_FILES, a trigger on this table, and a small PL/SQL package named XLIFF_TRANSFORM. The PL/SQL package parses the XML file and uses some XDB APIs to replace certain elements of the XML file. By exploiting the native functionality of the database, this was really quite easy to write. For anyone who says the Oracle database is only good for "persisting data", I say smoke this!

This isn't my ideal solution. In a future release of Application Express, I'd like to make it as simple as choosing to include your translations in your application export file, and they move around with you. As the metadata gets transformed on a new import, so do the translations. But until then, this solution can be used.

8 comments:

vgoncharov said...

Thank you very much for article "about savŠµd interactive reports". I wrote simple perl script to convert xliff for new app id.
Give 3 parameters to that script: xlf_from_orig_app.xlff xlf_from_new_app_id.xlf new_app_id

As a result you get xlf_from_new_app_id.xlf.new. Upload it to app with new id (new_app_id), apply and publish.
===
#!/usr/bin/perl
use Math::GMP; use bigint; use strict;
my ($f1,$f2,$id,$id1,$id2,$offset);
$f1=$ARGV[0];$f2=$ARGV[1];
open (F1,$f1) or die; open (F2,$f2) or die;
while() {
if (//) {
$id=$1;
if ($id=~/^\w\-[\d\.]+\-(\d+)\-\d+$/) {
$id1=$1; last;
} else {die $id}
}
}
die unless $id1;
while() {
if (//) {
$id=$1;
if ($id=~/^\w\-[\d\.]+\-(\d+)\-\d+$/) {
$id2=$1; last;
} else {die $id;}
}
}
die unless $id2;
$id1 = Math::GMP->new($id1);
$id2 = Math::GMP->new($id2);
$offset=$id2-$id1;
print "offset=".$offset."\n";
close F1; close F2;
open (F1,$f1) or die;
open (F2,">$f2.new") or die;
while () {
if (//) {
$id = $1;
if ($id=~/^(\w\-([\d\.]+\-)?)(\d+)(\-\d+)$/) {
$id1=$3;
} else {die $id}
$id1=Math::GMP->new($id1);
$id2=$id1+$offset;
print F2 "\n";
} else {
print F2 $_;
}
}
===
This script is just lazy example without multiple checks. But it works for me.

Joel, thank you again for this knolidge. God bless you.

Jock said...

I assume you don't encounter this issue if you just apply the XLIFF upload to your dev environment, and then for test/prod etc. just do an export and import of the "hidden" translated app?
That's the approach that we've taken and I haven't encountered any issues (so far)!

Joel R. Kallman said...

@drjfmiller - That's correct. This doesn't really apply to your case. It would be relevant if you wanted to import from one dev environment to another and in the process, change your application ID.

Joel

Sion said...

Hi Joel. Thank you for this app. I transform my XLIFF before and have no errors, but now I have a problem. I try to transformed XLIFF file and when click "Transform", have a error.

ORA-06502: PL/SQL: numeric or value error: character to number conversion error

I chek application ID and offset, it ok.

Joel R. Kallman said...

Sion,

How can I reproduce your issue? I tried out the hosted version of my application on apex.oracle.com and I did not encounter this error.

Joel

Vincent said...

I noticed the "New Application Offset " item requires a positive value as the "Minimum Value" is set to zero.

Why is that?

My new application ID needed to be inferior to the first.

I removed the "Minimum Value" and it worked.

Thanks for the application it saved me a lot of trouble.

Vincent

Vincent said...
This comment has been removed by the author.
Joel R. Kallman said...

Vincent,

I'm glad this worked for you.

In the forthcoming Application Express 4.1, you (finally) will be able to export your translations with your application export file. So customers will hopefully never face this roadblock again.

Joel