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

Parents Reply Children
  • Exactly. I automatically export the untranslated strings of my Passolo projects.

    However, the script above imports the text of an import file into all my target languages.

    I've added the condition in line 70 and it works fine now. Just to let you all know.

    '#Reference {F5078F18-C551-11D3-89B9-0000F81FE221}#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 DOMDocument60
    	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 SAXXMLReader60
    	Dim wrt As New MXXMLWriter60
    	Dim XLIFFfile As Object
    	Dim FileStringCount As Integer
    
    
    	Set fso = CreateObject("Scripting.FileSystemObject")
    
    
    	' Create the XLIFF object
    
    	Set XLIFFDoc=CreateObject("Msxml2.DOMDocument.6.0")
    
    	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")
    	Set 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 "http://xml.org/sax/properties/lexical-handler", wrt
    	rdr.putProperty "http://xml.org/sax/properties/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 DOMDocument60
    	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.6.0")
    
    	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)
    			If LCase(PSL.GetLangCode(translst.Language.LangID,pslCodeTrados))=target_language Then
    
    				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
    
    			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