Public/Export-XliffFile.ps1
|
function Export-XliffFile { <# .SYNOPSIS Writes translation unit changes back to an XLIFF file. .DESCRIPTION Applies in-memory changes from **XliffTranslationUnit** objects to their backing XML nodes, then saves the document to disk. Typical usage is to import, modify, and export in one pipeline: Import-XliffFile .\fr-FR.xlf | Set-XliffTranslationUnit -Id 'Table 1 - Field 1' -Target 'Client' -PassThru | Export-XliffFile -Path .\fr-FR.xlf The command preserves namespaces, `xsi:schemaLocation`, notes, attributes, and existing formatting wherever possible because it edits nodes in place rather than serializing new XML. If your input objects came from `Import-XliffFile -Streaming` or were created manually, supply **-TemplatePath** so the exporter can locate the matching `<trans-unit>` nodes by **Id**. .PARAMETER InputObject Translation units to export. Usually piped from `Import-XliffFile` or `Set-XliffTranslationUnit`. .PARAMETER Path Destination `.xlf` path. Parent directories are created automatically. .PARAMETER TemplatePath Optional template `.xlf` file used when **InputObject** instances do not contain backing XML nodes. .PARAMETER PassThru Returns the fully resolved output path after the file is saved. .OUTPUTS [string] The saved file path when `-PassThru` is specified. .EXAMPLE $units = Import-XliffFile .\Translations\Systemization.fr-FR.xlf $units | Export-XliffFile -Path .\Translations\Systemization.fr-FR.xlf Re-saves imported units without modification (useful after manual property edits). .EXAMPLE Import-XliffFile .\Translations\Systemization.fr-FR.xlf | Set-XliffTranslationUnit -Id 'Report 50000 - Label 1' -Target 'Solde du' -PassThru | Export-XliffFile -Path .\Translations\Systemization.fr-FR.xlf Updates one target and writes the file back. .NOTES Author: XliffParser Contributors Units that cannot be matched to a node in the target document are skipped with a warning instead of failing the entire export. #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory, ValueFromPipeline)] [ValidateNotNull()] [XliffTranslationUnit[]]$InputObject, [Parameter(Mandatory, Position = 0)] [ValidateNotNullOrEmpty()] [string]$Path, [ValidateNotNullOrEmpty()] [string]$TemplatePath, [switch]$PassThru ) begin { $units = [System.Collections.Generic.List[XliffTranslationUnit]]::new() } process { foreach ($unit in $InputObject) { $units.Add($unit) } } end { if ($units.Count -eq 0) { throw 'No translation units were provided.' } $document = $null if ($TemplatePath) { $document = Read-XliffXmlDocument -Path $TemplatePath $documentUnits = Get-XliffTranslationUnitsFromDocument -Document $document -Path (Resolve-XliffPath -Path $TemplatePath) $documentMap = $documentUnits | Get-XliffUnitMap } else { $document = $units[0].XmlDocument if (-not $document) { throw 'InputObject does not include backing XML. Provide -TemplatePath or use objects returned by Import-XliffFile without -Streaming.' } $documentMap = @{} foreach ($unit in $units) { if ($unit.Id) { $documentMap[$unit.Id] = $unit } } } foreach ($unit in $units) { $targetUnit = if ($unit.XmlNode -and -not $TemplatePath) { $unit } elseif ($unit.Id -and $documentMap.ContainsKey($unit.Id)) { $documentMap[$unit.Id] } else { $null } if (-not $targetUnit -or -not $targetUnit.XmlNode) { Write-Warning "Skipping unit '$($unit.Id)' because it was not found in the target document." continue } [void](Set-XliffUnitTarget -UnitNode ([System.Xml.XmlElement]$targetUnit.XmlNode) -Target $unit.Target) Set-XliffUnitState -UnitNode ([System.Xml.XmlElement]$targetUnit.XmlNode) -State $unit.State } if ($PSCmdlet.ShouldProcess($Path, 'Save XLIFF file')) { $savedPath = Save-XliffXmlDocument -Document $document -Path $Path if ($PassThru) { $savedPath } } } } |