I had been working this up on and off (mostly off) for a few months. This works with XML exports of the Translation Manager, and will handle multiple locales at once. You will need a Microsoft Azure account, but the free version is, as of this writing, 2 million characters per month.
-
Export XMLs from Translation Manager
-
Run the script in whatever fashion you choose.
-
Resultant files will be in the same directory.
-
Import the translated files back into the Translation Manager.
NOTE: Currently, the locales are not being correncly parsed when importing back in. (see this post). But, manually selecting the locale dropdown will let you work around it.
import javax.xml.parsers
import javax.xml.transform
import java.io.FileOutputStream as FOS
import httplib, urllib, uuid, codecs, os, glob
# **********************************************
# *** Update or verify the following values. ***
# **********************************************
# Replace the subscriptionKey string value with your valid subscription key.
subscriptionKey = 'put_your_own_key_here'
host = 'api.cognitive.microsofttranslator.com'
path = '/translate?api-version=3.0'
#*************************************************
filepath = system.file.openFile()
# Flag to tell it we are processing all of the files are just the selected one.
allFiles = True
if filepath != None:
# Base file name without locale
baseName = filepath[:-7]
# Extension of the file
extension = filepath[-4:]
if allFiles == True:
fileFilter = baseName + '*' + extension
else:
fileFilter = filepath
# create file list
fileList = glob.glob(fileFilter)
# create list of locales
langList = [f.replace(baseName,'').replace(extension, '')[1:] for f in fileList]
# create language parameters to use with Microsoft Translate
params = '&to='+'&to='.join(langList)
# open the selected file and extract keys to be translated
dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance()
db = dbf.newDocumentBuilder()
dom = db.parse(filepath)
doc = dom.getDocumentElement()
entries = doc.getElementsByTagName('entry')
keyList =[]
for i in range(entries.getLength()):
node = entries.item(i)
keyList.append(node.getAttribute('key'))
# header for Microsoft Translate API call
headers = {
'Ocp-Apim-Subscription-Key': subscriptionKey,
'Content-type': 'application/json',
'X-ClientTraceId': str(uuid.uuid4())
}
# serialize dictionary for use in Microsoft Translate API call
requestBody = []
for key in keyList:
requestBody.append({'Text' : key})
content = system.util.jsonEncode(requestBody)
# send request to Microsoft Translate
conn = httplib.HTTPSConnection(host)
conn.request ("POST", path + params, content, headers)
# get response
response = conn.getresponse()
data = response.read()
translatedData = system.util.jsonDecode(data)
# create dictionary with all translated data
dictOut = dict((key,{}) for key in keyList)
for key, t in zip(keyList, translatedData):
for language, translation in zip(langList, t['translations']):
dictOut[key][language]=translation['text']
# create output XML files
for lang in langList:
fileName = baseName + '_' + lang + '_output' + extension
dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance()
db = dbf.newDocumentBuilder()
dom = db.newDocument()
# XML root
root = dom.createElement('properties')
#create 'comment' element with locale
e = dom.createElement('comment')
e.appendChild(dom.createTextNode('Locale: '+lang))
# add 'comment' element to root
root.appendChild(e)
# add translations
for key in keyList:
# create entry element
e = dom.createElement('entry')
# add 'key' attibute with original text
e.setAttribute('key', key)
# add translated data for the key entry
e.appendChild(dom.createTextNode(dictOut[key][lang].decode('utf-8')))
# add 'entry' element to root
root.appendChild(e)
#close root
dom.appendChild(root)
# prepare xml file properties
tr = javax.xml.transform.TransformerFactory.newInstance().newTransformer()
tr.setOutputProperty(javax.xml.transform.OutputKeys.INDENT, 'yes')
tr.setOutputProperty(javax.xml.transform.OutputKeys.METHOD, 'xml')
tr.setOutputProperty(javax.xml.transform.OutputKeys.ENCODING, 'UTF-8')
tr.setOutputProperty(javax.xml.transform.OutputKeys.DOCTYPE_SYSTEM, 'http://java.sun.com/dtd/properties.dtd')
tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "0")
# convert XML data to a DOM source for writing to a file
domSource = javax.xml.transform.dom.DOMSource(dom)
# prepare FileOutputStream
streamFile = FOS(fileName)
# create StreamResult from FileOutputStream
streamOut = javax.xml.transform.stream.StreamResult(streamFile)
# write the DOM source to a file
tr.transform(domSource, streamOut)
# close the file
streamOut.getOutputStream().close()
Disclaimer below, but here’s the TLDR version: It works for me, YMMV. Consider yourself warned.
Disclimer: While Jordan has made every attempt to ensure that the information contained in this post has been obtained from reliable sources, Jordan is not responsible for any errors or omissions, or for the results obtained from the use of this information. All information in this post is provided “as is”, with no guarantee of completeness, accuracy, timeliness or of the results obtained from the use of this information, and without warranty of any kind, express or implied, including, but not limited to warranties of performance, merchantability and fitness for a particular purpose. In no event will Jordan, his related partnerships or corporations, or the partners, agents or employees thereof be liable to you or anyone else for any decision made or action taken in reliance on the information in this post or for any consequential, special or similar damages, even if advised of the possibility of such damages.