Any coders here to fix the XLIFF export/import macro?

There is this xliff export/import macro here.  One other user reported that it does not work, and I can confirm it.

As far as I can undertand the VBA code (and I wrote a bunch of VBA macros myself), the macro fails (at least on my computer) on trying to create the XLIFF document object. I was trying to use it in Passolo 2015 Translator Edition. Unfortunately VBA programming for XML is beyond me.

I would be nice if someone could fix the code, and it would be even nicer if someone could improve it, for example mark units that are outside my split, and those that use "Unify..." as untranslatale?

Thanks,

Piotr

  • This is the macro. The error is "Expecting a valid data type (eg. Integer)." and it higlights "Dim XLIFFDoc As DOMDocument".
    Downloadable here www.translatum.gr/.../index.php

    '#Reference {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}#6.0#0#C:\WINDOWS\system32\msxml6.dll#Microsoft XML, v6.0
    ''Export files to XLIFF document for processing in a TM system
    ''Import translated XLIFF documents
    ' -------------------------------
    ' Version 1.0 Laszlo Kovacs 13 April August 2009.
    ' -------------------------------
    ' Macro executes on:
    ' Projects Active/opened translation bundles.
    ' Source lists N/A
    ' Target lists ALL
    ' ===============================


    Option Explicit

    Dim translst As PslTransList
    Dim translsts As PslTransLists
    Dim transstr As PslTransString
    Dim i, j As Long
    Dim myBundle As PslProject
    Dim ExportTranslated, ExportForReview, ExportUntranslated As Boolean
    Dim source_language, target_language As String

    Const ForWriting = 2


    Private Sub ExportXLIFFFile()

    Dim fso As Object

    Dim XLIFFDoc As DOMDocument
    Dim XLIFFElem As IXMLDOMElement
    Dim newFileNode As IXMLDOMElement
    Dim newStringNode As IXMLDOMElement
    Dim newSourceString As IXMLDOMElement
    Dim newTargetString As IXMLDOMElement
    Dim newNoteString As IXMLDOMElement
    Dim rdr As New SAXXMLReader
    Dim wrt As New MXXMLWriter
    Dim XLIFFfile As Object
    Dim FileStringCount As Integer


    Set fso = CreateObject("Scripting.FileSystemObject")


    ' Create the XLIFF object

    Set XLIFFDoc=CreateObject("Msxml2.DOMDocument")

    XLIFFDoc.async=False
    XLIFFDoc.preserveWhiteSpace=True



    PSL.Output ("Preparing XLIFF data...")


    ' Create the root node.

    Set XLIFFElem = XLIFFDoc.createNode(1,"xliff","")
    XLIFFElem.setAttribute("version","1.2")
    XLIFFDoc.documentElement = XLIFFElem



    For i = 1 To myBundle.TransLists.Count
    Set translst = myBundle.TransLists(i)

    If LCase(PSL.GetLangCode(translst.Language.LangID,pslCodeTrados))=target_language Then
    source_language =LCase(PSL.GetLangCode(translst.SourceList.LangID,pslCodeTrados))

    PSL.Output ("Processing "+ CStr(i) + "/" + CStr(myBundle.TransLists.Count) + " - " + translst.Title)
    Set newFileNode = XLIFFDoc.createNode(1,"file","")
    newFileNode.setAttribute("original",StrReverse(Left(StrReverse(translst.TargetFile),(InStr(StrReverse(translst.TargetFile), "\") - 1))))
    newFileNode.setAttribute("source-language",source_language)
    newFileNode.setAttribute("target-language",target_language)
    newFileNode.setAttribute("datatype","plaintext")


    XLIFFElem.appendChild(newFileNode)
    FileStringCount=0


    On Error GoTo nextStringList
    For j = 1 To translst.StringCount
    Set transstr = translst.String(j)

    If ExportTranslated And transstr.State(pslStateTranslated) Then
    FileStringCount=FileStringCount+1
    Set newStringNode = XLIFFDoc.createNode(1,"trans-unit","")
    newStringNode.setAttribute("id",transstr.ID)
    newStringNode.setAttribute("approved","yes")
    newStringNode.setAttribute("translate","yes")
    newFileNode.appendChild(newStringNode)

    Set newSourceString = XLIFFDoc.createNode(1,"source","")
    newSourceString.Text= transstr.SourceText
    newStringNode.appendChild(newSourceString)

    Set newTargetString = XLIFFDoc.createNode(1,"target","")
    newTargetString.Text= transstr.Text
    newStringNode.appendChild(newTargetString)

    Set newNoteString = XLIFFDoc.createNode(1,"note","")
    newNoteString.Text= translst.Title + " - " + transstr.Description + Chr(13) + "Passolo Comment: " + transstr.Comment
    newStringNode.appendChild(newNoteString)




    ElseIf ExportForReview And transstr.State(pslStateReview) Then
    FileStringCount=FileStringCount+1
    Set newStringNode = XLIFFDoc.createNode(1,"trans-unit","")
    newStringNode.setAttribute("id",transstr.ID)
    newStringNode.setAttribute("approved","no")
    newStringNode.setAttribute("translate","yes")
    newFileNode.appendChild(newStringNode)

    Set newSourceString = XLIFFDoc.createNode(1,"source","")
    newSourceString.Text= transstr.SourceText
    newStringNode.appendChild(newSourceString)

    Set newTargetString = XLIFFDoc.createNode(1,"target","")
    newTargetString.Text= transstr.Text
    newStringNode.appendChild(newTargetString)

    Set newNoteString = XLIFFDoc.createNode(1,"note","")
    newNoteString.Text= translst.Title + " - " + transstr.Description + Chr(13) + "Passolo Comment: " + transstr.Comment
    newStringNode.appendChild(newNoteString)



    ElseIf ExportUntranslated And Not transstr.State(pslStateTranslated) And transstr.SourceText<>"" And Not transstr.State(pslStateReadOnly) Then
    FileStringCount=FileStringCount+1
    Set newStringNode = XLIFFDoc.createNode(1,"trans-unit","")
    newStringNode.setAttribute("id",transstr.ID)
    newStringNode.setAttribute("approved","no")
    newStringNode.setAttribute("translate","yes")
    newFileNode.appendChild(newStringNode)

    Set newSourceString = XLIFFDoc.createNode(1,"source","")
    newSourceString.Text= transstr.SourceText
    newStringNode.appendChild(newSourceString)

    Set newTargetString = XLIFFDoc.createNode(1,"target","")
    newTargetString.Text= ""
    newStringNode.appendChild(newTargetString)

    Set newNoteString = XLIFFDoc.createNode(1,"note","")
    newNoteString.Text= translst.Title + " - " + transstr.Description + Chr(13) + "Passolo Comment: " + transstr.Comment
    newStringNode.appendChild(newNoteString)


    End If

    Next j

    If FileStringCount=0 Then XLIFFElem.removeChild(newFileNode)


    nextstringlist:
    If Err.Description <>"" Then
    PSL.Output("Skipping " & translst.Title & ": " & Err.Description)
    Err.Clear
    End If
    Else
    PSL.Output("Skipping " & translst.Title & ": the language does not match")
    End If
    Next i


    wrt.byteOrderMark = False
    wrt.omitXMLDeclaration = False
    wrt.indent = True
    wrt.standalone=True
    wrt.encoding="UTF-8"


    'Set the XML writer to the SAX content handler.
    Set rdr.contentHandler = wrt
    Set rdr.dtdHandler = wrt
    Set rdr.errorHandler = wrt
    rdr.putProperty "xml.org/.../lexical-handler", wrt
    rdr.putProperty "xml.org/.../declaration-handler", wrt
    'Parse the DOMDocument object.
    rdr.parse XLIFFDoc

    'Open the file for writing

    Set XLIFFfile = fso.OpenTextFile(myBundle.Location & "\" & myBundle.Name & "_" & target_language & ".xlf" , ForWriting, True, True)
    XLIFFfile.Write (wrt.Output)


    ' XLIFFDoc.Save(myBundle.Location & "\" & myBundle.Name & ".xlf")


    End Sub

    Private Sub ImportXLIFFFile()

    Dim ImportSuccess, ImportAll, ImportFail As Long
    Dim Translatable As Boolean
    Dim XLIFFDoc As DOMDocument
    Dim XLIFFElem As IXMLDOMElement
    Dim newFileNode As IXMLDOMElement
    Dim newStringNode As IXMLDOMElement
    Dim newSourceString As IXMLDOMElement
    Dim newTargetString As IXMLDOMElement
    Dim newNoteString As IXMLDOMElement
    ' Create the XLIFF object

    Set XLIFFDoc=CreateObject("Msxml2.DOMDocument")

    XLIFFDoc.async=False



    PSL.Output ("Reading XLIFF data...")

    XLIFFDoc.load("file://" & myBundle.Location & "\" & myBundle.Name & "_" & target_language & ".xlf")

    Set XLIFFElem = XLIFFDoc.documentElement


    If XLIFFDoc.parseError.reason = "" Then

    For i = 1 To myBundle.TransLists.Count
    ImportSuccess=0
    ImportFail=0
    ImportAll=0
    Set translst = myBundle.TransLists(i)

    Set newFileNode = XLIFFElem.firstChild

    While Not newFileNode Is XLIFFElem.lastChild And newFileNode.attributes.getNamedItem("original").Text <> StrReverse(Left(StrReverse(translst.TargetFile),(InStr(StrReverse(translst.TargetFile), "\") - 1)))
    Set newFileNode = newFileNode.nextSibling
    Wend

    If newFileNode.attributes.getNamedItem("original").Text=StrReverse(Left(StrReverse(translst.TargetFile),(InStr(StrReverse(translst.TargetFile), "\") - 1))) Then


    For j = 1 To translst.StringCount

    Set transstr = translst.String(j)

    Translatable= (Not transstr.State(pslStateTranslated) Or transstr.State(pslStateReview)) And Not transstr.State(pslStateReadOnly) And Not transstr.State(pslStateLocked)

    If Translatable Then

    ImportAll = ImportAll + 1

    Set newStringNode = newFileNode.firstChild

    While Not newStringNode Is newFileNode.lastChild And Not (newStringNode.attributes.getNamedItem("id").Text=CStr(transstr.ID) And newStringNode.firstChild.Text = Trim(transstr.SourceText))
    Set newStringNode = newStringNode.nextSibling
    Wend

    If newStringNode.attributes.getNamedItem("id").Text = CStr(transstr.ID) And newStringNode.firstChild.Text = Trim(transstr.SourceText) Then
    transstr.Text= Replace(transstr.SourceText, Trim(transstr.SourceText), newStringNode.firstChild.nextSibling.Text)
    transstr.State(pslStateTranslated)=True
    transstr.State(pslStateReview)=True
    ImportSuccess=ImportSuccess+1
    Else
    ImportFail=ImportFail+1
    End If
    End If

    Next j

    translst.Save

    PSL.Output ("Processed "+ CStr(i) + "/" + CStr(myBundle.TransLists.Count) + " - " + translst.Title+" Translated "+CStr(ImportSuccess)+" of "+CStr(ImportAll) + " strings")

    End If
    Next i
    Else
    PSL.Output ("Processing failed: "+ XLIFFDoc.parseError.reason)
    End If


    End Sub



    Sub Main

    Dim Bundle As PslProject
    Dim TargetLanguageList() As String
    Dim knownLang As Boolean

    ReDim TargetLanguageList(0)

    PSL.OutputWnd.Clear
    PSL.Output("Scanning open bundles for target languages...")

    For Each Bundle In PSL.Projects
    For Each translst In Bundle.TransLists
    target_language = LCase(PSL.GetLangCode(translst.Language.LangID,pslCodeTrados))
    knownLang=False
    For i=0 To UBound(TargetLanguageList)

    If TargetLanguageList(i) = target_language Then knownLang=True
    Next
    If Not knownLang Then
    If TargetLanguageList(UBound(TargetLanguageList))<>"" Then ReDim Preserve TargetLanguageList(UBound(TargetLanguageList)+1)
    TargetLanguageList(UBound(TargetLanguageList))=target_language
    End If
    Next
    Next



    Begin Dialog UserDialog 690,364,"Export and import XLIFF" ' %GRID:10,7,1,1
    GroupBox 10,7,670,56,"Scope",.grpScope
    GroupBox 10,63,670,252,"Operation",.grpOperation
    PushButton 420,329,130,21,"Start",.cmdOK
    CancelButton 570,329,100,21,.cmdCancel
    Text 10,343,90,14,"v.1.0",.lblMacroVersion
    Text 60,280,610,28,"Import reads the following XLIFF file: <Path_of_Passolo_Bundle>\<Name_of_Passolo_Bundle>_<lang>.xlf",.lblInstruction
    Text 70,91,450,28,"Export creates the following XLIFF file: <Path_of_Passolo_Bundle>\<Name_of_Passolo_Bundle>_<lang>.xlf",.lblInstruction2
    GroupBox 50,119,620,140,"Status Filter",.grpStatus
    CheckBox 60,210,400,14,"Export Translated strings",.ExportTranslated
    CheckBox 60,168,400,14,"Export ForReview strings",.ExportForReview
    CheckBox 60,140,400,14,"Export untranslated strings",.ExportUntranslated
    Text 90,154,560,14,"The XLIFF attribute of untranslated strings is NOT approved, the target string is empty",.lblExportUntranslated
    Text 100,224,550,28,"The XLIFF attribute of translated strings is approved, the target string contains the current text in Passolo",.lblExportTranslated
    Text 90,182,550,28,"The XLIFF attribute of For review strings is NOT approved, the target string contains the current text in Passolo",.lblExportForReview
    OptionGroup .ExportImport
    OptionButton 30,77,190,14,"Export for translation",.optExport
    OptionButton 20,266,190,14,"Import translations",.optImport
    OptionGroup .ScopeOption
    OptionButton 30,21,200,14,"Process the active bundle",.optActiveBundle
    OptionButton 30,42,220,14,"Process all opened bundles",.optAllOpenedBundles
    Text 310,21,180,14,"Target language to extract:",.lblLanguage
    DropListBox 510,21,90,70,TargetLanguageList,.lstLanguage,1
    End Dialog

    Dim dlg As UserDialog

    dlg.lstLanguage=TargetLanguageList(0)
    If PSL.Projects.Count=1 Then dlg.ScopeOption=0
    If PSL.Projects.Count>1 Then dlg.ScopeOption=1
    dlg.ExportImport=0
    dlg.ExportTranslated=True
    dlg.ExportForReview=True
    dlg.ExportUntranslated=True

    If Dialog(dlg) = 0 Then
    Exit Sub
    Else

    target_language = dlg.lstLanguage
    ExportTranslated=dlg.ExportTranslated
    ExportForReview=dlg.ExportForReview
    ExportUntranslated=dlg.ExportUntranslated
    If dlg.ScopeOption =0 Then
    Set myBundle = PSL.ActiveProject
    If dlg.exportimport=0 Then
    ExportXLIFFFile
    Else
    ImportXLIFFFile
    End If
    Else
    For Each Bundle In PSL.Projects
    Set myBundle = Bundle
    PSL.Output("Processing " & myBundle.Name)
    If dlg.exportimport=0 Then
    ExportXLIFFFile
    Else
    ImportXLIFFFile
    End If
    Next
    End If
    End If

    Done:
    PSL.Output ("--- Done ---")

    End Sub

    emoji
  • This is an old topic, but I ran into the same problem yesterday so I think it is still of interest. Therefore I attach updated macros that can be used to export Passolo projects (.tbulic18) from Passolo Translator Edition 2018 into TMX and XLIFF files for use in e.g. Trados Studio. All credit to whoever wrote the original macros. I am no expert, my code changes are based on simple internet searches.

    Installation:
    Copy the macros to C:\Users\Public\Documents\Passolo Translator 2018\Macros

    Running:
    Tools > Macros > Macro List, select the macro and click Run. The .tmx or .xlf is saved in the same folder as the .tbulic18.

    Comments:
    The original macros are available at How to Export Text from Passolo File (direct link: translation-blog.com/.../Passolo.zip), but they were written for a previous MSXML version and produce errors when you try to run them. To fix the errors I just made these minor code changes:

    – DOMDocument > DOMDocument60
    – SAXXMLReader  > SAXXMLReader60
    – MXXMLWriter > MXXMLWriter60
    – Msxml2.DOMDocument > Msxml2.DOMDocument.6.0

    That is all that was needed to make the XLIFF macro work.

    The TMX macro still didn't produce a valid TMX that could be imported into an SDLTM and to fix that I made these additional changes:
    – Inserted an empty <header/> tag
    – Deleted all code lines related to notes, since the original macro inserted <note> elements inside <tuv> elements which Trados didn't like. Perhaps these note elements could be moved up one level instead, as direct children to the <tu> element, but I haven't looked into that. Feel free to improve.

  • Sorry for late reply Stepan. I may not be correctly subscribed to this topic so I don't receive an e-mail if there are replies.

    Perhaps this is too late for you, but I have put the files in a personal cloud account now so hopefully they won't disappear this time:

  • Hi ,
    Things like this are never late. I managed to fix Passolo-to-XLF macro for my purposes and it works fine. Thank you. But I have no idea what to do with the other two, Passolo-to-tmx and Passolo-to-ttx. Unfortunately, your new "link is no longer available" too.

  • Whenever I try to paste a link, it gets automatically scrambled by this platform, and the correct characters are replaced by "xxxxxx...". I don't know what to do, it doesn't matter if I paste it as plain text or create a Link and insert it as an URL. Please tell me how I can post the correct link.

    Edit: I inserted the link as an image above. I don't know why it's so complicated to paste a simple link.

    Please tell me if you received it Stepan, otherwise I'll mail to you :-)

  • The screenshot link has worked. There are 2 macros, but I don't think I ever come across ttx files again. Thank you so much! This macro (Passolo-to-XLF) saved me billions of nerve cells.

    h​t​t​p​s​:​/​/​w​w​w​.​o​d​r​i​v​e​.​c​o​m​/​s​/​c​0​9​9​3​b​2​6​-​4​3​3​7​-​4​8​7​e​-​8​9​0​8​-​c​e​b​b​3​8​0​6​5​7​1​1​-​6​0​b​1​5​7​f​0

  • I noticed that the XLF and TMX export macros had stopped working in Passolo 2022 Translator Edition so I made some minor adjustments to get them going again, just changing one line of code in each .bas file.

    I also noticed that the previous link to the files wasn't working anymore since it had been accessed more than 50 times, so I have updated that one as well now pointing to a Dropbox folder which will hopefully work better:

    Passolo macros

    emoji