PowerShell: XLIFF (.xlf) Trans-Unit-IDs abgleichen

25. Juli 2018 11:44

Mit diesem Skript kann man zwei XLIFF-Dateien dahingehend abgleichen, ob die Trans-Unit-IDs aus Datei 1 auch in Datei 2 zu finden sind.

Die beiden Dateien können dabei wie üblich über Explorerfenster ausgewählt werden.
Es wird dabei eine neue XLIFF-Datei erzeugt, welche alle Trans-Unit-Sections aus Datei 1 enthält, die nicht in Datei 2 zu finden waren.
Die neue Datei (Suffix _MissingTransUnits im Dateinamen) wird in dem Ordner von Datei 1 erzeugt. Wenn der Vergleich abgeschlossen ist, wird dieser im Explorer geöffnet.

Zur Laufzeit sieht man diese Anzeige durchlaufen (Grün: gefunden, Rot: nicht gefunden :wink: )
CompareTransUnitIDs.png


Die erzeugte Datei kann man dann einfach im Dateivergleicher gegen Datei 1 stellen um die Fehlstellen zu ermitteln (etwas, was mit den Ausgangsdateien wegen der nicht steuerbaren Platzierung der Trans-Unit-Sections bei der automatischen Erzeugung aus Txt2AL und mit AL in VSCode leider nicht direkt möglich ist, wenn es sich nicht um die 'en-US' im Vergleich zur Generic-Datei handelt, die beim Kompilieren erzeugt wird).
XLIFFcompare.png


Code:
Function CompareXLIFFs
{
    $ErrorActionPreference = "Stop"
    $PSDefaultParameterValues['*:ErrorAction']='Stop'
    Function Get-FileName($initialDirectory, $FileName)
    {
        [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
   
        $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
        $OpenFileDialog.initialDirectory = $initialDirectory
        $OpenFileDialog.Title = $FileName
        $OpenFileDialog.filter = "XLIFF (*.xlf)|*.xlf|All files (*.*)|*.*"
        $OpenFileDialog.ShowDialog() | Out-Null
        $OpenFileDialog.filename
    }
       
    $inputfile1 = Get-FileName 'C:\temp' 'Select XLIFF 1'
    if ($inputfile1 -eq "") {throw 'Please select a file'}

    $WorkingFolder = Split-Path -Parent $inputfile1

    $inputfile2 = Get-FileName $WorkingFolder 'Select XLIFF 2'
    if ($inputfile2 -eq "") {throw 'Please select a file'}
       
    $SourceEncoding = [System.Text.Encoding]::GetEncoding(65001)
    #$targetEncoding = [System.Text.Encoding]::GetEncoding(65001)

    $textfile2 = [System.IO.File]::ReadAllText($inputfile2, $sourceencoding)
    $sr1 = new-object System.IO.StreamReader($inputfile1,$SourceEncoding)
    $sr2 = new-object System.IO.StreamReader($inputfile2,$SourceEncoding)
    $sw = new-object System.IO.Streamwriter("$inputfile1.tmp",$false,$SourceEncoding)
    $convertedFileName = [System.IO.Path]::GetFileNameWithoutExtension($inputfile1) +"_MissingTransUnits" + [System.IO.Path]::GetExtension($inputfile1)
    $convertedfile = New-Item -path "$WorkingFolder\$convertedFileName" -type file -force
    IF (Test-Path $ConvertedFile) {Remove-Item $ConvertedFile}
    #IF (Test-Path "$inputfile1.tmp") {Remove-Item "$inputfile1.tmp"}

    $Headerline1 = '<?xml version="1.0" encoding="utf-8"?>'
    $Headerline2 ='<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"'
    $Headerline3 ='<file datatype="xml"'
    $Headerline4 ='<body>'
    $Headerline5 ='<group id="body">'
    $Footerline1 ='</file>'
    $Footerline2 ='</body>'
    $Footerline3 ='</group>'
    $Footerline4 ='</xliff>'

    while (-not $sr1.EndOfStream)
    {

        $TokenStart = '        <trans-unit id='
        $TokenEnd = '        </trans-unit>'


        $Currline = $Sr1.ReadLine()
        #Write-host $Currline
       
        $TrimmedCurrline = $Currline.TrimStart()
        #Write-host $TrimmedCurrline
        $IsHeaderLine = ($TrimmedCurrline -eq $Headerline1) -or
        ($TrimmedCurrline.Startswith($Headerline2)) -or
        ($TrimmedCurrline.Startswith($Headerline3)) -or
        ($TrimmedCurrline -eq $Headerline4) -or
        ($TrimmedCurrline -eq $Headerline5)

        $IsFooterLine = ($TrimmedCurrline -eq $Footerline1) -or
        ($TrimmedCurrline -eq $Footerline2) -or
        ($TrimmedCurrline -eq $Footerline3) -or
        ($TrimmedCurrline -eq $Footerline4)

        if ($Currline.StartsWith($TokenStart))
        {
            $IDexists = $False
            $dblQts = [char]34

            $Currline2 = $Currline.Substring(24)
            #Write-host $Currline2
            $dblQtsPos = $Currline2.indexof($dblQts)
            #Write-host $dblQtsPos 
            $IDsub = $Currline2.Substring(0,$dblQtsPos)
            #Write-host $IDsub
            $TransUnitSection = $true
            $EndofTransUnitSection = $false
            $OldValueTransUnitSection = $true
            #$Probe = Select-String -inputobject $sr2 -Pattern $Idsub -simplematch -CaseSensitive
            $Probe = Select-String -path $inputfile2 -Pattern $Idsub -simplematch -CaseSensitive
            $IDexists = ($Probe -ne $null)
            if ($IDexists)
            {
                Write-host "$IDexists for $Idsub" -ForegroundColor Green
            }
            else
            {
                Write-host "$IDexists for $Idsub" -ForegroundColor Red
                #Write-host "$IDexists" -ForegroundColor Yellow
            }
       
        }
       
       
       
        if ($OldValueTransUnitSection)
        {
            if (($TransUnitSection) -and ($Currline.Startswith($TokenEnd)))
            {
                                   
                                     
                $EndofTransUnitSection = $true
                $OldValueTransUnitSection = $false
            }
        }
       

        if ($IsHeaderLine -or $isFooterline)
        {
            $sw.writeline($Currline)
        }               
       
        IF (-not ($IDexists))
        {
            if ($TransUnitSection)

            {
                $sw.writeline($Currline)
       
            }
        }
                       
        if ($EndofTransUnitSection)
        {           
            $OldValueTransunitSection = $False
            $TransUnitSection = $False
            $IDexists = $false
        }
       
    }

    $sr1.Close()
    $sr1.Dispose()
    $sr2.Close()
    $sr2.Dispose()

    $sw.close()
    $sw.Dispose()
    Rename-Item -path "$inputfile1.tmp" -NewName $convertedFileName -force -verbose
    Invoke-item -Path $WorkingFolder

}
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.