Modules/businessdev.ALbuild.Apps/Public/Set-BcTranslationUnit.ps1
|
function Set-BcTranslationUnit { <# .SYNOPSIS Sets the target text (and state) of a single translation unit in an AL XLIFF file. .DESCRIPTION The supported, auditable single-unit write path behind `albuild translation set` - no raw XML editing. Selects the unit by id or by exact source text, writes the <target>, and sets its state: 'translated' (a completed translation) or 'needs-work' (mapped to the XLIFF 'needs-adaptation' state). Namespace-agnostic (XLIFF 1.2/2.0) via the shared Get-BcXliffUnit reader. .PARAMETER Path The target-language XLIFF file to edit. .PARAMETER Id The trans-unit id to set. Either -Id or -Source is required. .PARAMETER Source The exact source text to match. Either -Id or -Source is required. .PARAMETER Target The translated text to write into <target>. .PARAMETER State 'translated' (default) or 'needs-work'. .OUTPUTS PSCustomObject { id, source, target, state, file }. #> [CmdletBinding(SupportsShouldProcess)] [OutputType([PSCustomObject])] param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $Path, [string] $Id, [string] $Source, [Parameter(Mandatory)] [AllowEmptyString()] [string] $Target, [ValidateSet('translated', 'needs-work')] [string] $State = 'translated' ) if (-not (Test-Path -LiteralPath $Path)) { throw "XLIFF file not found: '$Path'." } if ([string]::IsNullOrEmpty($Id) -and [string]::IsNullOrEmpty($Source)) { throw 'Specify -Id or -Source to select the translation unit.' } [xml] $doc = Get-Content -LiteralPath $Path -Raw -Encoding UTF8 $units = @(Get-BcXliffUnit -Document $doc) $match = if ($Id) { $units | Where-Object { $_.Id -eq $Id } | Select-Object -First 1 } else { $units | Where-Object { $_.Source -eq $Source } | Select-Object -First 1 } if (-not $match) { $sel = if ($Id) { "id '$Id'" } else { "source '$Source'" } throw "No translation unit found for $sel in '$Path'." } $sourceNode = $match.SourceNode $targetNode = $match.TargetNode if (-not $targetNode) { $ns = $sourceNode.NamespaceURI $targetNode = if ($ns) { $doc.CreateElement('target', $ns) } else { $doc.CreateElement('target') } $null = $sourceNode.ParentNode.InsertAfter($targetNode, $sourceNode) } $targetNode.InnerText = $Target # State lives on <target>. A completed translation carries state="translated"; needs-work maps to the # XLIFF "needs-adaptation" state that Test-BcTranslation flags as incomplete. $xlfState = if ($State -eq 'needs-work') { 'needs-adaptation' } else { 'translated' } $stateAttr = $targetNode.Attributes | Where-Object { $_.Name -ieq 'state' } | Select-Object -First 1 if (-not $stateAttr) { $stateAttr = $targetNode.SetAttributeNode($doc.CreateAttribute('state')) } $stateAttr.Value = $xlfState if ($PSCmdlet.ShouldProcess($Path, "Set translation unit '$($match.Id)'")) { $doc.Save($Path) Write-ALbuildLog -Level Success "Set '$($match.Id)' in '$(Split-Path -Leaf $Path)' -> $State." } return [PSCustomObject]@{ id = $match.Id; source = $match.Source; target = $Target; state = $State; file = (Split-Path -Leaf $Path) } } |