PowerShell: Aus XLIFF eine NAV-Translationsdatei erzeugen

24. August 2015 00:07

Die Rückumwandlung einer überarbeiteten XLIFF-Datei in eine NAV-Translate Datei ist mittels der in PowerShell direkt nutzbaren XMl-DOM-Funktionen vergleichsweise sehr schnell möglich, da die Nodes mit den IDs der Sourcelanguage (Quellsprache) und die beiden Übersetzungen hier direkt gelesen werden können.
Als Eingabe ist hierbei nur der Pfad zur XLIFF-Datei erforderlich, der Dateiname der .xlf-Datei wird dabei wegen der folgenden Umwandlung von UTF8 nach OEM 850 mit Suffix "_OEM850.txt" ergänzt.

Die NAV-Sprachcodes ergeben sich dabei aus den ISO 639-Sprachcodes der XLIFF (die Switch-Befehle zum Mappen der Codes ggf. nach Bedarf erweitern), da für Österreich (de -> DEA -> A3079) kein separater 'de'-Code vorhanden ist, muss das Skript hierfür in den Switch-Befehlen angepasst werden (de -> DEU -> A1031 auskommentieren) , wenn IDs mit diesen Codes erzeugt werden sollen bzw. in der XLIFF vorhanden sind.

Bei manuellen Änderungen in der XLIFF mit ",',<,> und & (XML Reserved Characters) beachten, dass diese Zeichen maskiert werden müssen (Link). In der NAV-Translationsdatei werden diese dann richtig dargestellt.

Durch die Verwendung des Industriestandards XLIFF ist es mit dieser und der Funktion XLIFF-Datei aus NAV-Translationsdatei erzeugen somit problemlos möglich, Übersetzungen auch durch externe Dienstleister durchführen zu lassen und anschließend in NAV zu übernehmen. Aktuelle Objektversionen ab NAV 2013 können per Cmdlets bedient werden, alternativ bzw. in älteren NAV-Versionen im Objektdesigner den Objektdatum, Zeit und Geändert-Status der betroffenen Objekte per Report sichern, die NAV-Translationsdatei importieren und anschließend den Objektstatus wieder zurückschreiben.

Ausgangsdatei
XLFToTrans.jpg

Überarbeitete Datei
XLFToTrans1.png


Code:
function XLFtoNAVtransFile
{
$XLFtransfile = Read-host "Path of XLIFF file"
$FileExtension = [System.IO.Path]::GetExtension($XLFtransfile)
if (!($FileExtension -eq '.xlf')) {Throw 'Please use a XLIFF file with .xlf extension for this script.'}
$NAVoutfile = [System.IO.Path]::GetDirectoryName($XLFtransfile) + "\"+ [System.IO.Path]::GetFileNameWithoutExtension($XLFtransfile) + '.txt'
if ($XLFtransfile -eq $NAVoutfile)
  {
   Throw "Source and target file are identical. Source: $XLFtransfile Target: $NAVoutfile"
  }

if (test-path $NAVoutfile) {remove-item -path $NAVoutfile}

$xml = [xml] (get-content $XLFtransfile -Encoding UTF8)

foreach ($XLFnode in $xml.GetElementsByTagName('trans-unit'))
{
$sourceid = $XLFnode.getAttribute("id")

ForEach ($item in $XLFnode)
{
$sourceLanguage = $item.source.'lang'.ToString()
Switch ($SourceLanguage)
    {
    "dk" {$NAVSourcelangCode = '-A1030-'}
    "de" {$NAVSourcelangCode = '-A1031-'}
    "en" {$NAVSourcelangCode = '-A1033-'}
    "es" {$NAVSourcelangCode = '-A1034-'}
    "fi" {$NAVSourcelangCode = '-A1035-'}
    "fr" {$NAVSourcelangCode = '-A1036-'}
    "it" {$NAVSourcelangCode = '-A1040-'}
    "nl" {$NAVSourcelangCode = '-A1043-'}
    "no" {$NAVSourcelangCode = '-A1044-'}
    "pl" {$NAVSourcelangCode = '-A1045-'}
    "pt" {$NAVSourcelangCode = '-A1046-'}
    "se" {$NAVSourcelangCode = '-A1053-'}
    "gsw" {$NAVSourcelangCode = '-A2055-'}
    "en-gb" {$NAVSourcelangCode = '-A2057-'}
    # "de" {$NAVlangCode = '-A3079-'} # activate in AT and deactivate de -> A1031
    default {Throw "Please assign a NAV translation code for $NAVSourcelangCode  in the script"}
    }
$sourceCaption = $item.source.'#text'.ToString()
$sourceline = $sourceid + ':' + $sourcecaption
Out-File $NAVoutfile -inputobject $sourceline -Encoding UTF8 -force -Append -Width 1024

$TargetLanguage = $item.target.'lang'.ToString()
$TargetCaption = $item.target.'#text'.ToString()
Switch ($TargetLanguage)
    {
    "dk" {$NAVTargetlangCode = '-A1030-'}
    "de" {$NAVTargetlangCode = '-A1031-'}
    "en" {$NAVTargetlangCode = '-A1033-'}
    "es" {$NAVTargetlangCode = '-A1034-'}
    "fi" {$NAVTargetlangCode = '-A1035-'}
    "fr" {$NAVTargetlangCode = '-A1036-'}
    "it" {$NAVTargetlangCode = '-A1040-'}
    "nl" {$NAVTargetlangCode = '-A1043-'}
    "no" {$NAVTargetlangCode = '-A1044-'}
    "pt" {$NAVTargetlangCode = '-A1046-'}
    "se" {$NAVTargetlangCode = '-A1053-'}
    "gsw" {$NAVTargetlangCode = '-A2055-'}
    "en-gb" {$NAVTargetlangCode = '-A2057-'}
    # "de" {$NAVlangCode = '-A3079-'} # activate in AT and deactivate de -> A1031
    default {Throw "Please assign a NAV translation code for $NAVTargetlangCode in the script"}
    }

$targetid = $sourceid -replace $NAVSourcelangCode, $NAVTargetlangCode
$targetline = $targetid + ':' + $targetcaption
Out-File $NAVoutfile -inputobject $targetline -Encoding UTF8 -force -Append -Width 1024
}
}
$sourceEncoding = [System.Text.Encoding]::GetEncoding(65001)
$targetEncoding = [System.Text.Encoding]::GetEncoding(850)
$convertedFileName = [System.IO.Path]::GetDirectoryName($NAVoutfile) + "\"+ [System.IO.Path]::GetFileNameWithoutExtension($NAVoutfile) +"_OEM850" + [System.IO.Path]::GetExtension($NAVoutfile)
if (Test-Path $convertedFileName) {Remove-Item $convertedFileName}
$convertedfile = New-Item -path $convertedFileName -type file
$textfile = [System.IO.File]::ReadAllText($NAVoutfile, $sourceencoding)
[System.IO.File]::WriteAllText($convertedfile, $textfile, $targetencoding)
if (Test-Path $NavOutFile) {Remove-Item $NAVoutfile}
Write-host $XLFtransfile 'converted to' $convertedFileName
}
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

Re: PowerShell: Aus XLIFF eine NAV-Translationsdatei erzeuge

25. Januar 2019 10:01

Bei dieser Variante kommt die Zusatzfrage
Do you want to write the source language to the NAV file (yes,no) ?

damit man optional die Ausgangssprache weglassen kann, falls man Bedenken hat, dass die nach der Übersetzung ebenfalls hier und da versehentlich zur Zielsprache wurde :wink: . Somit kann man bei "no" ein Überschreiben der Captions der Ausgangssprache verhindern.

Code:
function XLFtoNAVtransFile2
{

$XLFtransfile = Read-host "Path of XLIFF file"
$FileExtension = [System.IO.Path]::GetExtension($XLFtransfile)
if (!($FileExtension -eq '.xlf')) {Throw 'Please use a XLIFF file with .xlf extension for this script.'}


$NAVoutfile = [System.IO.Path]::GetDirectoryName($XLFtransfile) + "\"+ [System.IO.Path]::GetFileNameWithoutExtension($XLFtransfile) + '.txt'
if ($XLFtransfile -eq $NAVoutfile)
  {
   Throw "Source and target file are identical. Source: $XLFtransfile Target: $NAVoutfile"
  }

if (test-path $NAVoutfile) {remove-item -path $NAVoutfile}

[ValidateSet('yes','no')]$WriteSourceCaptions = Read-Host "Do you want to write the source language to the NAV file (yes,no) ?"


$xml = [xml] (get-content $XLFtransfile -Encoding UTF8)

foreach ($XLFnode in $xml.GetElementsByTagName('trans-unit'))
{
$sourceid = $XLFnode.getAttribute("id")

ForEach ($item in $XLFnode)
{
$sourceLanguage = $item.source.'lang'.ToString()
Switch ($SourceLanguage)
    {
    "dk" {$NAVSourcelangCode = '-A1030-'}
    "de" {$NAVSourcelangCode = '-A1031-'}
    "en" {$NAVSourcelangCode = '-A1033-'}
    "es" {$NAVSourcelangCode = '-A1034-'}
    "fi" {$NAVSourcelangCode = '-A1035-'}
    "fr" {$NAVSourcelangCode = '-A1036-'}
    "it" {$NAVSourcelangCode = '-A1040-'}
    "nl" {$NAVSourcelangCode = '-A1043-'}
    "no" {$NAVSourcelangCode = '-A1044-'}
    "pl" {$NAVSourcelangCode = '-A1045-'}
    "pt" {$NAVSourcelangCode = '-A1046-'}
    "se" {$NAVSourcelangCode = '-A1053-'}
    "gsw" {$NAVSourcelangCode = '-A2055-'}
    "en-gb" {$NAVSourcelangCode = '-A2057-'}
    # "de" {$NAVlangCode = '-A3079-'} # activate in AT and deactivate de -> A1031
    default {Throw "Please assign a NAV translation code for $NAVSourcelangCode  in the script"}
    }
$sourceCaption = $item.source.'#text'.ToString()
$sourceline = $sourceid + ':' + $sourcecaption

if ($WriteSourceCaptions -eq 'yes')
{Out-File $NAVoutfile -inputobject $sourceline -Encoding UTF8 -force -Append -Width 1024}

$TargetLanguage = $item.target.'lang'.ToString()
$TargetCaption = $item.target.'#text'.ToString()
Switch ($TargetLanguage)
    {
    "dk" {$NAVTargetlangCode = '-A1030-'}
    "de" {$NAVTargetlangCode = '-A1031-'}
    "en" {$NAVTargetlangCode = '-A1033-'}
    "es" {$NAVTargetlangCode = '-A1034-'}
    "fi" {$NAVTargetlangCode = '-A1035-'}
    "fr" {$NAVTargetlangCode = '-A1036-'}
    "it" {$NAVTargetlangCode = '-A1040-'}
    "nl" {$NAVTargetlangCode = '-A1043-'}
    "no" {$NAVTargetlangCode = '-A1044-'}
    "pt" {$NAVTargetlangCode = '-A1046-'}
    "se" {$NAVTargetlangCode = '-A1053-'}
    "gsw" {$NAVTargetlangCode = '-A2055-'}
    "en-gb" {$NAVTargetlangCode = '-A2057-'}
    # "de" {$NAVlangCode = '-A3079-'} # activate in AT and deactivate de -> A1031
    default {Throw "Please assign a NAV translation code for $NAVTargetlangCode in the script"}
    }

$targetid = $sourceid -replace $NAVSourcelangCode, $NAVTargetlangCode
$targetline = $targetid + ':' + $targetcaption
Out-File $NAVoutfile -inputobject $targetline -Encoding UTF8 -force -Append -Width 1024
}
}
$sourceEncoding = [System.Text.Encoding]::GetEncoding(65001)
$targetEncoding = [System.Text.Encoding]::GetEncoding(850)
$convertedFileName = [System.IO.Path]::GetDirectoryName($NAVoutfile) + "\"+ [System.IO.Path]::GetFileNameWithoutExtension($NAVoutfile) +"_OEM850" + [System.IO.Path]::GetExtension($NAVoutfile)
if (Test-Path $convertedFileName) {Remove-Item $convertedFileName}
$convertedfile = New-Item -path $convertedFileName -type file
$textfile = [System.IO.File]::ReadAllText($NAVoutfile, $sourceencoding)
[System.IO.File]::WriteAllText($convertedfile, $textfile, $targetencoding)
if (Test-Path $NavOutFile) {Remove-Item $NAVoutfile}
Write-host $XLFtransfile 'converted to' $convertedFileName
}