Fix ID scanning in form-add and title emission in form-compile

form-add: Scan column IDs (same pool as attribute IDs) to prevent
duplicate ID collisions. Use XPath .//*[@id] instead of ChildItems
recursion to capture companion element IDs (ExtendedTooltip, ContextMenu).

form-compile: Extract title from properties and route through Emit-MLText
instead of generic Emit-Properties, which produced plain text <Title>
rejected by 1C XDTO schema.

Found during E2E testing of full pipeline (epf-init → form-compile →
form-add → epf-build).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-02-09 14:40:23 +03:00
parent 99f57a5ff2
commit a9e59265dd
2 changed files with 41 additions and 27 deletions
+22 -22
View File
@@ -63,37 +63,37 @@ $script:nextElemId = 0
$script:nextAttrId = 0
$script:nextCmdId = 0
function Scan-ElementIds($node) {
foreach ($child in $node.ChildNodes) {
if ($child.NodeType -ne 'Element') { continue }
$id = $child.GetAttribute("id")
if ($id -and $id -ne "" -and $id -ne "-1") {
try {
$intId = [int]$id
if ($intId -gt $script:nextElemId) { $script:nextElemId = $intId }
} catch {}
# Scan ALL element IDs via XPath (includes companions like ExtendedTooltip, ContextMenu)
$rootCI = $root.SelectSingleNode("f:ChildItems", $nsMgr)
if ($rootCI) {
foreach ($elem in $rootCI.SelectNodes(".//*[@id]")) {
$id = $elem.GetAttribute("id")
if ($id -and $id -ne "-1") {
try { $intId = [int]$id; if ($intId -gt $script:nextElemId) { $script:nextElemId = $intId } } catch {}
}
$ci = $child.SelectSingleNode("f:ChildItems", $nsMgr)
if ($ci) { Scan-ElementIds $ci }
}
}
$acb = $root.SelectSingleNode("f:AutoCommandBar", $nsMgr)
if ($acb) {
$id = $acb.GetAttribute("id")
if ($id -and $id -ne "-1") {
try { $intId = [int]$id; if ($intId -gt $script:nextElemId) { $script:nextElemId = $intId } } catch {}
}
}
$rootCI = $root.SelectSingleNode("f:ChildItems", $nsMgr)
if ($rootCI) { Scan-ElementIds $rootCI }
# Also scan AutoCommandBar children
$acb = $root.SelectSingleNode("f:AutoCommandBar", $nsMgr)
if ($acb) {
$acbCI = $acb.SelectSingleNode("f:ChildItems", $nsMgr)
if ($acbCI) { Scan-ElementIds $acbCI }
}
# Scan attribute IDs
# Scan attribute IDs (including column IDs — same pool)
foreach ($attr in $root.SelectNodes("f:Attributes/f:Attribute", $nsMgr)) {
$id = $attr.GetAttribute("id")
if ($id) {
try { $intId = [int]$id; if ($intId -gt $script:nextAttrId) { $script:nextAttrId = $intId } } catch {}
}
# Column IDs are in the same pool as attribute IDs
foreach ($col in $attr.SelectNodes("f:Columns/f:Column", $nsMgr)) {
$colId = $col.GetAttribute("id")
if ($colId) {
try { $intColId = [int]$colId; if ($intColId -gt $script:nextAttrId) { $script:nextAttrId = $intColId } } catch {}
}
}
}
# Scan command IDs
@@ -978,13 +978,27 @@ $script:nextId = 1
X '<?xml version="1.0" encoding="UTF-8"?>'
X '<Form xmlns="http://v8.1c.ru/8.3/xcf/logform" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:dcscor="http://v8.1c.ru/8.1/data-composition-system/core" xmlns:dcssch="http://v8.1c.ru/8.1/data-composition-system/schema" xmlns:dcsset="http://v8.1c.ru/8.1/data-composition-system/settings" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.17">'
# 12a. Title
if ($def.title) {
Emit-MLText -tag "Title" -text "$($def.title)" -indent "`t"
# 12a. Title (from def.title or properties.title — must be multilingual XML)
$formTitle = $def.title
if (-not $formTitle -and $def.properties -and $def.properties.title) {
$formTitle = $def.properties.title
}
if ($formTitle) {
Emit-MLText -tag "Title" -text "$formTitle" -indent "`t"
}
# 12b. Properties
Emit-Properties -props $def.properties -indent "`t"
# 12b. Properties (skip 'title' — handled above as multilingual)
if ($def.properties) {
$propsClone = New-Object PSObject
foreach ($p in $def.properties.PSObject.Properties) {
if ($p.Name -ne "title") {
$propsClone | Add-Member -NotePropertyName $p.Name -NotePropertyValue $p.Value
}
}
Emit-Properties -props $propsClone -indent "`t"
} else {
Emit-Properties -props $null -indent "`t"
}
# 12c. CommandSet (excluded commands)
if ($def.excludedCommands -and $def.excludedCommands.Count -gt 0) {