mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-08-18 09:10:21 +03:00
feat(mxl-compile,mxl-decompile): значение ячейки-поля ввода и настройки элемента управления
Ключ ячейки value несёт значение, набранное в поле ввода, ключ control — сериализованные настройки самого элемента управления. Оба живут у ячейки, а не в палитре формата: у двух ячеек с одинаковым оформлением значения разные. Тип значения выражается литералом JSON и приведения к объявленному типу НЕ делается. Так пишет платформа: ссылочный и составной тип она хранит строкой, а при смене типа ячейки прежнее значение не переписывает — на корпусе 560 ячеек объявлены числом, но несут строку. Приведение здесь означало бы переписывать данные при пересборке. Дата литералом JSON не выражается, поэтому едет строкой и читается как дата только у ячейки, объявленной датой. Настройки элемента управления возим дословно: 26 370 вхождений корпуса дают всего 163 различных блоба, разбирать структуру незачем. Переводы строк внутри блоба приводим к LF на чтении — XML-парсеры двух портов нормализуют их по-разному, и без этого порты давали разный JSON на одном файле. Стенд СЗначениями снова собирается байт в байт обоими портами: фикстура обновлена до версии со значениями, флажком и блобом настроек. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
66bb285636
commit
43d2f660da
@@ -1,4 +1,4 @@
|
||||
# mxl-decompile v1.21 — Decompile 1C spreadsheet to JSON
|
||||
# mxl-decompile v1.22 — Decompile 1C spreadsheet to JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -92,6 +92,25 @@ $valueControlNames = @{
|
||||
# значение» без указания типа — самостоятельное состояние.
|
||||
# Префикс ссылочного типа разрешаем по URI, а не по имени: локальное объявление платформа
|
||||
# называет сгенерированным dNpM. Чужое пространство имён оставляем как есть.
|
||||
# Значение ячейки-поля ввода → литерал DSL. Тип значения выражается самим литералом:
|
||||
# число → числом, булево → true/false, строка и дата → строкой. Пустое значение пишем
|
||||
# как есть (0, false, пустая дата), а не схлопываем: так оно собирается обратно тем же
|
||||
# типом независимо от того, какой тип объявлен у ячейки.
|
||||
function ConvertTo-DslValue {
|
||||
param([string]$xsiType, [string]$text)
|
||||
if ($null -eq $text) { $text = '' }
|
||||
if ($xsiType -ceq 'xs:boolean') { return ($text.Trim() -ceq 'true') }
|
||||
if ($xsiType -ceq 'xs:decimal') {
|
||||
$s = $text.Trim()
|
||||
$i = 0; $d = 0.0
|
||||
if ($s -notlike '*.*' -and [int]::TryParse($s, [ref]$i)) { return $i }
|
||||
if ([double]::TryParse($s, [System.Globalization.NumberStyles]::Float,
|
||||
[System.Globalization.CultureInfo]::InvariantCulture, [ref]$d)) { return $d }
|
||||
return $s
|
||||
}
|
||||
return $text
|
||||
}
|
||||
|
||||
function Get-ValueQualifier {
|
||||
param($quals, [string]$kind, [string]$name, [string]$default = '')
|
||||
if (-not $quals.ContainsKey($kind)) { return $default }
|
||||
@@ -390,6 +409,22 @@ foreach ($riNode in $root.SelectNodes("d:rowsItem", $ns)) {
|
||||
$dNode = $cContent.SelectSingleNode("d:detailParameter", $ns)
|
||||
if ($dNode) { $detail = $dNode.InnerText }
|
||||
|
||||
# Значение ячейки-поля ввода. Тип значения свой, из объявленного не выводится,
|
||||
# поэтому читаем и его.
|
||||
$value = $null
|
||||
$vNode = $cContent.SelectSingleNode("d:v", $ns)
|
||||
if ($vNode) {
|
||||
$value = @{ Type = $vNode.GetAttribute("type", "http://www.w3.org/2001/XMLSchema-instance"); Text = $vNode.InnerText }
|
||||
}
|
||||
|
||||
# Настройки элемента управления — сериализованный base64 у самой ячейки.
|
||||
# Структуру не разбираем, возим дословно.
|
||||
$control = $null
|
||||
$ctlNode = $cContent.SelectSingleNode("d:control", $ns)
|
||||
# Переводы строк внутри блоба приводим к LF: XML-парсеры нормализуют их
|
||||
# по-разному, и без этого порты давали разный JSON на одном файле.
|
||||
if ($ctlNode -and $ctlNode.InnerText) { $control = $ctlNode.InnerText -replace "`r`n", "`n" }
|
||||
|
||||
# Текст ячейки платформа хранит по элементу на язык. Раньше брался ПЕРВЫЙ, и всё
|
||||
# остальное терялось — в корпусе ERP 98% макетов держат текст и под ru, и под en.
|
||||
# Здесь собираем «язык → текст» как есть; свернётся в строку позже, когда станет
|
||||
@@ -423,6 +458,8 @@ foreach ($riNode in $root.SelectNodes("d:rowsItem", $ns)) {
|
||||
FormatIdx = $cellFmtIdx
|
||||
Param = $param
|
||||
Detail = $detail
|
||||
Value = $value
|
||||
Control = $control
|
||||
Text = $text
|
||||
HasText = $hasText
|
||||
}
|
||||
@@ -1135,6 +1172,10 @@ foreach ($area in $blocks) {
|
||||
# форматах корпуса.
|
||||
if ($name -cne 'input') { $dslCell["controlType"] = $name }
|
||||
}
|
||||
if ($null -ne $cell.Value) {
|
||||
$dslCell["value"] = ConvertTo-DslValue $cell.Value.Type $cell.Value.Text
|
||||
}
|
||||
if ($cell.Control) { $dslCell["control"] = $cell.Control }
|
||||
}
|
||||
|
||||
# Content
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# mxl-decompile v1.21 — Decompile 1C spreadsheet to JSON
|
||||
# mxl-decompile v1.22 — Decompile 1C spreadsheet to JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -187,6 +187,23 @@ def value_type_to_dsl(node):
|
||||
return ' + '.join(parts)
|
||||
|
||||
|
||||
def value_to_dsl(xsi_type, text):
|
||||
"""Значение ячейки-поля ввода → литерал DSL. Тип значения выражается самим литералом:
|
||||
число → числом, булево → true/false, строка и дата → строкой. Пустое значение пишем
|
||||
как есть (0, false, пустая дата), а не схлопываем: так оно собирается обратно тем же
|
||||
типом независимо от того, какой тип объявлен у ячейки."""
|
||||
text = text or ''
|
||||
if xsi_type == 'xs:boolean':
|
||||
return text.strip() == 'true'
|
||||
if xsi_type == 'xs:decimal':
|
||||
s = text.strip()
|
||||
try:
|
||||
return int(s) if '.' not in s else float(s)
|
||||
except ValueError:
|
||||
return s
|
||||
return text
|
||||
|
||||
|
||||
def int_of(node, default=0):
|
||||
if node is not None and node.text:
|
||||
return int(node.text)
|
||||
@@ -556,6 +573,22 @@ def main():
|
||||
if d_node is not None and d_node.text:
|
||||
detail = d_node.text
|
||||
|
||||
# Значение ячейки-поля ввода. Тип значения свой, из объявленного не выводится,
|
||||
# поэтому читаем и его: пустое значение сворачивается в "", остальные едут как есть.
|
||||
value = None
|
||||
v_node = find(c_content, "d:v")
|
||||
if v_node is not None:
|
||||
value = (v_node.get(f'{{{XSI_NS}}}type') or '', (v_node.text or ''))
|
||||
|
||||
# Настройки элемента управления — сериализованный base64 у самой ячейки.
|
||||
# Структуру не разбираем, возим дословно.
|
||||
control = None
|
||||
ctl_node = find(c_content, "d:control")
|
||||
if ctl_node is not None and ctl_node.text:
|
||||
# Переводы строк внутри блоба приводим к LF: XML-парсеры нормализуют их
|
||||
# по-разному, и без этого порты давали разный JSON на одном файле.
|
||||
control = ctl_node.text.replace('\r\n', '\n')
|
||||
|
||||
# Текст ячейки платформа хранит по элементу на язык. Раньше брался ПЕРВЫЙ, и всё
|
||||
# остальное терялось — в корпусе ERP 98% макетов держат текст и под ru, и под en.
|
||||
# Здесь собираем «язык → текст» как есть; свернётся в строку позже, когда станет
|
||||
@@ -587,6 +620,8 @@ def main():
|
||||
"FormatIdx": cell_fmt_idx,
|
||||
"Param": param,
|
||||
"Detail": detail,
|
||||
"Value": value,
|
||||
"Control": control,
|
||||
"Text": text,
|
||||
"HasText": has_text,
|
||||
})
|
||||
@@ -1128,6 +1163,10 @@ def main():
|
||||
# форматах корпуса.
|
||||
if name != "input":
|
||||
dsl_cell["controlType"] = name
|
||||
if cell["Value"] is not None:
|
||||
dsl_cell["value"] = value_to_dsl(*cell["Value"])
|
||||
if cell["Control"]:
|
||||
dsl_cell["control"] = cell["Control"]
|
||||
|
||||
# Content
|
||||
fill_type = cell_fmt["FillType"] if cell_fmt else ""
|
||||
|
||||
Reference in New Issue
Block a user