feat(skd): пустые detail/totalExpression в userFields

В UserFieldExpression XML присутствуют все 4 элемента (detailExpression,
detailExpressionPresentation, totalExpression, totalExpressionPresentation),
даже когда они пустые (<dcsset:totalExpression/>). Раньше пустые опускались.

decompile теперь читает по присутствию узла, compile эмитит self-closing
форму для пустых строк.

sample30: −106 строк (3743 → 3637).
This commit is contained in:
Nick Shirokov
2026-05-23 13:03:24 +03:00
parent a66246095c
commit 5e864cb05f
3 changed files with 49 additions and 27 deletions
@@ -1,4 +1,4 @@
# skd-compile v1.64 — Compile 1C DCS from JSON
# skd-compile v1.65 — Compile 1C DCS from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[string]$DefinitionFile,
@@ -2549,12 +2549,28 @@ function Emit-UserFields {
}
if ($uType -eq "UserFieldExpression") {
if ($uf.detail) {
if ($uf.detail.expression) { X "$indent`t`t<dcsset:detailExpression>$(Esc-Xml "$($uf.detail.expression)")</dcsset:detailExpression>" }
if ($uf.detail.presentation) { X "$indent`t`t<dcsset:detailExpressionPresentation>$(Esc-Xml "$($uf.detail.presentation)")</dcsset:detailExpressionPresentation>" }
if ($uf.detail.PSObject.Properties.Match('expression').Count -gt 0) {
$_v = "$($uf.detail.expression)"
if ($_v) { X "$indent`t`t<dcsset:detailExpression>$(Esc-Xml $_v)</dcsset:detailExpression>" }
else { X "$indent`t`t<dcsset:detailExpression/>" }
}
if ($uf.detail.PSObject.Properties.Match('presentation').Count -gt 0) {
$_v = "$($uf.detail.presentation)"
if ($_v) { X "$indent`t`t<dcsset:detailExpressionPresentation>$(Esc-Xml $_v)</dcsset:detailExpressionPresentation>" }
else { X "$indent`t`t<dcsset:detailExpressionPresentation/>" }
}
}
if ($uf.total) {
if ($uf.total.expression) { X "$indent`t`t<dcsset:totalExpression>$(Esc-Xml "$($uf.total.expression)")</dcsset:totalExpression>" }
if ($uf.total.presentation) { X "$indent`t`t<dcsset:totalExpressionPresentation>$(Esc-Xml "$($uf.total.presentation)")</dcsset:totalExpressionPresentation>" }
if ($uf.total.PSObject.Properties.Match('expression').Count -gt 0) {
$_v = "$($uf.total.expression)"
if ($_v) { X "$indent`t`t<dcsset:totalExpression>$(Esc-Xml $_v)</dcsset:totalExpression>" }
else { X "$indent`t`t<dcsset:totalExpression/>" }
}
if ($uf.total.PSObject.Properties.Match('presentation').Count -gt 0) {
$_v = "$($uf.total.presentation)"
if ($_v) { X "$indent`t`t<dcsset:totalExpressionPresentation>$(Esc-Xml $_v)</dcsset:totalExpressionPresentation>" }
else { X "$indent`t`t<dcsset:totalExpressionPresentation/>" }
}
}
} else {
# UserFieldCase
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# skd-compile v1.64 — Compile 1C DCS from JSON
# skd-compile v1.65 — Compile 1C DCS from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import json
@@ -2106,16 +2106,22 @@ def emit_user_fields(lines, items, indent):
if uf.get('title'):
emit_mltext(lines, f'{indent}\t\t', 'dcsset:lwsTitle', uf['title'], no_xsi_type=True)
if u_type == 'UserFieldExpression':
d = uf.get('detail') or {}
if d.get('expression'):
lines.append(f'{indent}\t\t<dcsset:detailExpression>{esc_xml(str(d["expression"]))}</dcsset:detailExpression>')
if d.get('presentation'):
lines.append(f'{indent}\t\t<dcsset:detailExpressionPresentation>{esc_xml(str(d["presentation"]))}</dcsset:detailExpressionPresentation>')
t = uf.get('total') or {}
if t.get('expression'):
lines.append(f'{indent}\t\t<dcsset:totalExpression>{esc_xml(str(t["expression"]))}</dcsset:totalExpression>')
if t.get('presentation'):
lines.append(f'{indent}\t\t<dcsset:totalExpressionPresentation>{esc_xml(str(t["presentation"]))}</dcsset:totalExpressionPresentation>')
d = uf.get('detail')
if d is not None:
if 'expression' in d:
v = str(d['expression'])
lines.append(f'{indent}\t\t<dcsset:detailExpression>{esc_xml(v)}</dcsset:detailExpression>' if v else f'{indent}\t\t<dcsset:detailExpression/>')
if 'presentation' in d:
v = str(d['presentation'])
lines.append(f'{indent}\t\t<dcsset:detailExpressionPresentation>{esc_xml(v)}</dcsset:detailExpressionPresentation>' if v else f'{indent}\t\t<dcsset:detailExpressionPresentation/>')
t = uf.get('total')
if t is not None:
if 'expression' in t:
v = str(t['expression'])
lines.append(f'{indent}\t\t<dcsset:totalExpression>{esc_xml(v)}</dcsset:totalExpression>' if v else f'{indent}\t\t<dcsset:totalExpression/>')
if 'presentation' in t:
v = str(t['presentation'])
lines.append(f'{indent}\t\t<dcsset:totalExpressionPresentation>{esc_xml(v)}</dcsset:totalExpressionPresentation>' if v else f'{indent}\t\t<dcsset:totalExpressionPresentation/>')
else:
cases = uf.get('cases') or []
if len(cases) == 0:
@@ -1,4 +1,4 @@
# skd-decompile v0.48 — Decompile 1C DCS Template.xml to JSON DSL (draft)
# skd-decompile v0.49 — Decompile 1C DCS Template.xml to JSON DSL (draft)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -2292,20 +2292,20 @@ foreach ($sv in $svNodes) {
$titleV = Get-MLText $titleN
if ($titleV) { $entry['title'] = $titleV }
if ($uxt -eq 'UserFieldExpression') {
$dEx = Get-Text $ufItem "dcsset:detailExpression"
$dEp = Get-Text $ufItem "dcsset:detailExpressionPresentation"
$tEx = Get-Text $ufItem "dcsset:totalExpression"
$tEp = Get-Text $ufItem "dcsset:totalExpressionPresentation"
if ($dEx -or $dEp) {
$dExN = $ufItem.SelectSingleNode("dcsset:detailExpression", $ns)
$dEpN = $ufItem.SelectSingleNode("dcsset:detailExpressionPresentation", $ns)
$tExN = $ufItem.SelectSingleNode("dcsset:totalExpression", $ns)
$tEpN = $ufItem.SelectSingleNode("dcsset:totalExpressionPresentation", $ns)
if ($dExN -or $dEpN) {
$d = [ordered]@{}
if ($dEx) { $d['expression'] = $dEx }
if ($dEp) { $d['presentation'] = $dEp }
if ($dExN) { $d['expression'] = $dExN.InnerText }
if ($dEpN) { $d['presentation'] = $dEpN.InnerText }
$entry['detail'] = $d
}
if ($tEx -or $tEp) {
if ($tExN -or $tEpN) {
$t = [ordered]@{}
if ($tEx) { $t['expression'] = $tEx }
if ($tEp) { $t['presentation'] = $tEp }
if ($tExN) { $t['expression'] = $tExN.InnerText }
if ($tEpN) { $t['presentation'] = $tEpN.InnerText }
$entry['total'] = $t
}
} elseif ($uxt -eq 'UserFieldCase') {