feat(form-decompile,form-compile): системные перечисления в choiceList + footerDataPath/footerText/editMode на labelField/radio + AdditionalColumns empty self-closing

Четыре находки из rt-iter2 (формы Хозрасчётный/ФормаСчёта, СпецификацииНоменклатуры):

1. **Системные перечисления в choiceList** (ent: namespace, напр. ent:AccountType=ВидСчёта):
   значение несёт xsi:type="ent:AccountType", компилятор эмитил xs:string (терял тип).
   Per-item ключ `valueType` (как у фильтра): декомпилятор сохраняет не-примитивный
   не-DesignTimeRef xsi:type, компилятор эмитит его вместо авто-детекта.
2. **footerDataPath/footerText на LabelField** — были только у InputField, на поле-надписи
   (колонка таблицы) терялись. Добавлены (decompile + compile, позиция по корпусу).
3. **editMode у RadioButtonField** — не ловился/не эмитился (форма ВидСчёта). Добавлен.
4. **Пустая AdditionalColumns** (table-ref без колонок) — компилятор эмитил пустую пару
   <AdditionalColumns table="X"></...>, платформа — self-closing. Фикс: self-closing при
   пустых columns.

Зеркало py. Обе формы → match. Кейсы radio-tumbler-strings (+ent:AccountType +editMode),
picture-field (labelField-колонка +footerDataPath/footerText), additional-columns
(+пустая группа) сертифицированы в 1С. Регресс 43/43 (ps1+py).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-06-11 21:32:04 +03:00
parent bdd38691aa
commit 330447c95f
11 changed files with 236 additions and 16 deletions
@@ -1,4 +1,4 @@
# form-compile v1.123 — Compile 1C managed form from JSON or object metadata
# form-compile v1.124 — Compile 1C managed form from JSON or object metadata
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[string]$JsonPath,
@@ -3895,7 +3895,15 @@ function Emit-ChoiceList {
elseif ($item.PSObject.Properties["title"]) { $presRaw = $item.title; $hasPres = $true }
}
$norm = Normalize-ChoiceValue -value $valRaw
# valueType: явный xsi:type значения (системное перечисление ent:*, иной не-примитив) —
# переопределяет авто-детект (Normalize-ChoiceValue вывела бы xs:string).
$vtRaw = $null
if ($item -is [hashtable] -or $item -is [System.Collections.IDictionary]) {
if ($item.Contains("valueType")) { $vtRaw = "$($item["valueType"])" }
} elseif ($item.PSObject.Properties["valueType"]) { $vtRaw = "$($item.valueType)" }
if ($vtRaw) { $norm = @{ XsiType = $vtRaw; Text = "$valRaw" } }
else { $norm = Normalize-ChoiceValue -value $valRaw }
# авто-вывод presentation, если не задан
if (-not $hasPres) {
@@ -4092,6 +4100,7 @@ function Emit-Radio {
Emit-Title -el $el -name $name -indent $inner -auto:(-not $el.path)
Emit-CommonFlags -el $el -indent $inner
if ($el.editMode) { X "$inner<EditMode>$($el.editMode)</EditMode>" }
Emit-TitleLocation -el $el -indent $inner -smartDefault "None"
# RadioButtonType: Auto | RadioButtons | Tumbler. Accept synonyms.
@@ -4181,6 +4190,8 @@ function Emit-LabelField {
if ($el.titleLocation) { X "$inner<TitleLocation>$(Map-TitleLoc "$($el.titleLocation)")</TitleLocation>" }
if ($el.editMode) { X "$inner<EditMode>$($el.editMode)</EditMode>" }
# FooterDataPath — путь данных подвала колонки (общий cell-prop, как у input); после EditMode
if ($el.footerDataPath) { X "$inner<FooterDataPath>$(Esc-Xml "$($el.footerDataPath)")</FooterDataPath>" }
# PasswordMode на LabelField — платформа эмитит явный false (редко); факт. значение
if ($null -ne $el.passwordMode) { X "$inner<PasswordMode>$(if ($el.passwordMode){'true'}else{'false'})</PasswordMode>" }
Emit-ColumnPics -el $el -indent $inner
@@ -4189,6 +4200,7 @@ function Emit-LabelField {
Emit-Layout -el $el -indent $inner
if ($null -ne $el.warningOnEdit) { Emit-MLText -tag "WarningOnEdit" -text $el.warningOnEdit -indent $inner }
if ($null -ne $el.footerText) { Emit-MLText -tag "FooterText" -text $el.footerText -indent $inner }
# Формат / формат редактирования (LocalStringType — строка или {ru,en})
if ($el.format) { Emit-MLText -tag "Format" -text $el.format -indent $inner }
@@ -5227,9 +5239,15 @@ function Emit-Attributes {
}
if ($hasAddCols) {
foreach ($ac in @($attr.additionalColumns)) {
$acCols = @($ac.columns)
if ($acCols.Count -eq 0) {
# Пустая группа доп.колонок (table-ref без колонок) → self-closing (как платформа)
X "$inner`t<AdditionalColumns table=`"$($ac.table)`"/>"
continue
}
X "$inner`t<AdditionalColumns table=`"$($ac.table)`">"
$seenAcCols = @{} # уникальность в пределах группы AdditionalColumns
foreach ($col in @($ac.columns)) {
foreach ($col in $acCols) {
Assert-UniqueName -name "$($col.name)" -seen $seenAcCols -kind "column of '$attrName'"
Emit-AttrColumn -col $col -indent "$inner`t`t"
}
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# form-compile v1.123 — Compile 1C managed form from JSON or object metadata
# form-compile v1.124 — Compile 1C managed form from JSON or object metadata
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import copy
@@ -2120,7 +2120,13 @@ def emit_choice_list(lines, el, indent):
has_pres = any(k in item for k in ('presentation', 'представление', 'title'))
pres_raw = item.get('presentation', item.get('представление', item.get('title')))
norm = normalize_choice_value(val_raw)
# valueType: явный xsi:type значения (системное перечисление ent:*, иной не-примитив) —
# переопределяет авто-детект (normalize_choice_value вывела бы xs:string).
vt_raw = item.get('valueType')
if vt_raw:
norm = {'xsi_type': str(vt_raw), 'text': '' if val_raw is None else str(val_raw)}
else:
norm = normalize_choice_value(val_raw)
if not has_pres:
if norm['xsi_type'] == 'xr:DesignTimeRef':
@@ -3817,6 +3823,8 @@ def emit_radio_button_field(lines, el, name, eid, indent):
emit_title(lines, el, name, inner, auto=not el.get('path'))
emit_common_flags(lines, el, inner)
if el.get('editMode'):
lines.append(f'{inner}<EditMode>{el["editMode"]}</EditMode>')
emit_title_location(lines, el, inner, 'None')
rbt = normalize_radio_button_type(el.get('radioButtonType'))
@@ -3898,6 +3906,9 @@ def emit_label_field(lines, el, name, eid, indent):
lines.append(f'{inner}<TitleLocation>{map_title_loc(el["titleLocation"])}</TitleLocation>')
if el.get('editMode'):
lines.append(f'{inner}<EditMode>{el["editMode"]}</EditMode>')
# FooterDataPath — путь данных подвала колонки (общий cell-prop, как у input); после EditMode
if el.get('footerDataPath'):
lines.append(f'{inner}<FooterDataPath>{esc_xml(str(el["footerDataPath"]))}</FooterDataPath>')
# PasswordMode на LabelField — платформа эмитит явный false (редко); факт. значение
if el.get('passwordMode') is not None:
lines.append(f'{inner}<PasswordMode>{"true" if el["passwordMode"] else "false"}</PasswordMode>')
@@ -3909,6 +3920,8 @@ def emit_label_field(lines, el, name, eid, indent):
if el.get('warningOnEdit') is not None:
emit_mltext(lines, inner, 'WarningOnEdit', el['warningOnEdit'])
if el.get('footerText') is not None:
emit_mltext(lines, inner, 'FooterText', el['footerText'])
# Формат / формат редактирования (LocalStringType — строка или {ru,en})
if el.get('format'):
@@ -4953,9 +4966,14 @@ def emit_attributes(lines, attrs, indent, conditional_appearance=None):
emit_attr_column(lines, col, f'{inner}\t')
if has_add_cols:
for ac in attr['additionalColumns']:
ac_cols = ac.get('columns') or []
if not ac_cols:
# Пустая группа доп.колонок (table-ref без колонок) → self-closing (как платформа)
lines.append(f'{inner}\t<AdditionalColumns table="{ac["table"]}"/>')
continue
lines.append(f'{inner}\t<AdditionalColumns table="{ac["table"]}">')
seen_ac_cols = set() # уникальность в пределах группы AdditionalColumns
for col in (ac.get('columns') or []):
for col in ac_cols:
_ensure_unique(str(col['name']), seen_ac_cols, f"column of '{attr_name}'")
emit_attr_column(lines, col, f'{inner}\t\t')
lines.append(f'{inner}\t</AdditionalColumns>')
@@ -1,4 +1,4 @@
# form-decompile v0.97 — Decompile 1C managed Form.xml to JSON DSL (draft)
# form-decompile v0.98 — Decompile 1C managed Form.xml to JSON DSL (draft)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
# ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью.
param(
@@ -1416,6 +1416,11 @@ function Decompile-ChoiceList {
if ($valNode) {
$xsiType = $valNode.GetAttribute("type", $NS_XSI)
$ci['value'] = Convert-TypedValue $valNode.InnerText $xsiType
# Системное перечисление (ent:*) / иной не-примитивный, не-DesignTimeRef тип → сохраняем
# valueType (Normalize-ChoiceValue в компиляторе вывела бы xs:string и потеряла тип).
if ($xsiType -and $xsiType -notmatch '^xs:(string|decimal|boolean|dateTime)$' -and $xsiType -ne 'xr:DesignTimeRef') {
$ci['valueType'] = $xsiType
}
}
# Presentation: непустой → текст/мультиязык; пустой <Presentation/> → "" — суппресс-маркер,
# подавляет авто-вывод компилятора (иначе компилятор додумает presentation из значения).
@@ -1666,6 +1671,7 @@ function Decompile-Element {
$dp = Get-Child $node 'DataPath'; if ($dp) { $obj['path'] = $dp }
Add-CommonProps $obj $node $name
Add-TitleLocation $obj $node 'None'
$em = Get-Child $node 'EditMode'; if ($em) { $obj['editMode'] = $em }
$rbt = Get-Child $node 'RadioButtonType'; if ($rbt) { $obj['radioButtonType'] = $rbt }
$cc = Get-Child $node 'ColumnsCount'; if ($cc) { $obj['columnsCount'] = [int]$cc }
$woe = $node.SelectSingleNode("lf:WarningOnEdit", $ns); if ($woe) { $t = Get-LangText $woe; if ($null -ne $t) { $obj['warningOnEdit'] = $t } }
@@ -1690,6 +1696,9 @@ function Decompile-Element {
# PasswordMode на LabelField — платформа эмитит явный false (редко); захват факт. значения
$pm = Get-Child $node 'PasswordMode'; if ($null -ne $pm) { $obj['passwordMode'] = ($pm -eq 'true') }
$woe = $node.SelectSingleNode("lf:WarningOnEdit", $ns); if ($woe) { $t = Get-LangText $woe; if ($null -ne $t) { $obj['warningOnEdit'] = $t } }
# FooterDataPath / FooterText — общие cell-свойства колонки (как у input), не только input
$fdp = Get-Child $node 'FooterDataPath'; if ($fdp) { $obj['footerDataPath'] = $fdp }
$ftxt = $node.SelectSingleNode("lf:FooterText", $ns); if ($ftxt) { $t = Get-LangText $ftxt; if ($null -ne $t) { $obj['footerText'] = $t } }
Add-FormatProps $obj $node
}
'PictureDecoration' {
+1
View File
@@ -489,6 +489,7 @@ companion-панели с собственным контентом. Оба не
| Свойство | Тип | Описание |
|----------|-----|----------|
| `value` | string/number/bool | Значение варианта. Для перечисления — `"Enum.ИмяТипа.EnumValue.ИмяЗначения"` (xsi:type автоматически: `xr:DesignTimeRef` / `xs:string` / `xs:decimal` / `xs:boolean`) |
| `valueType` | string | Явный xsi:type значения, переопределяет авто-детект. Нужен для **системных перечислений** (`ent:` namespace: `ent:AccountType`=ВидСчёта, `ent:AccumulationRecordType`, `ent:HorizontalAlignment`, … — см. «Системные перечисления» в палитре типов) и иных не-примитивных типов. Напр. `{ "value": "Active", "valueType": "ent:AccountType", "presentation": "Активный" }` |
| `presentation` | string или object | Текст рядом с переключателем. Строка → ru; объект `{ru, en, ...}` → мультиязык. Если не задано — выводится из имени значения |
#### label — LabelDecoration
@@ -7,7 +7,8 @@
"type": "DataProcessor",
"name": "ДопКолонки",
"tabularSections": [
{ "name": "Прочее", "attributes": [ { "name": "Значение", "type": "String", "length": 50 } ] }
{ "name": "Прочее", "attributes": [ { "name": "Значение", "type": "String", "length": 50 } ] },
{ "name": "ЕщёТаблица", "attributes": [ { "name": "Поле", "type": "String", "length": 10 } ] }
]
},
"args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" }
@@ -30,7 +31,8 @@
{ "table": "Объект.Прочее", "columns": [
{ "name": "Доступность", "type": "boolean" },
{ "name": "Служебная", "type": "string" }
]}
]},
{ "table": "Объект.ЕщёТаблица", "columns": [] }
]
}
]
@@ -21,7 +21,8 @@
"columns": [
{ "input": "ТаблицаДанныхНоменклатура", "path": "ТаблицаДанных.Номенклатура" },
{ "picField": "ТаблицаДанныхКартинка", "path": "ТаблицаДанных.Картинка", "titleLocation": "none", "editMode": "EnterOnInput", "hyperlink": true, "shortcut": "Ctrl+S", "headerPicture": "StdPicture.ExecuteTask", "valuesPicture": { "src": "StdPicture.FilterCriterion", "loadTransparent": true, "transparentPixel": { "x": 7, "y": 3 } } },
{ "check": "ТаблицаДанныхКартинкаФлаг", "path": "ТаблицаДанных.Картинка", "title": "Флаг", "headerPicture": { "src": "StdPicture.ClearFilter", "loadTransparent": true } }
{ "check": "ТаблицаДанныхКартинкаФлаг", "path": "ТаблицаДанных.Картинка", "title": "Флаг", "headerPicture": { "src": "StdPicture.ClearFilter", "loadTransparent": true } },
{ "labelField": "ТаблицаДанныхИтог", "path": "ТаблицаДанных.Номенклатура", "editMode": "EnterOnInput", "footerDataPath": "ТаблицаДанных.Номенклатура", "footerText": "Итого" }
]}
],
"attributes": [
@@ -26,11 +26,20 @@
"radio": "ОтборСтрок",
"path": "ОтборСтрок",
"radioButtonType": "Tumbler",
"editMode": "EnterOnInput",
"warningOnEdit": "Смена отбора перезагрузит список",
"choiceList": [
{ "value": "Рекомендуемые" },
{ "value": "Все" }
]
},
{
"radio": "ВидСчета",
"choiceList": [
{ "value": "Active", "valueType": "ent:AccountType", "presentation": "Активный" },
{ "value": "Passive", "valueType": "ent:AccountType", "presentation": "Пассивный" },
{ "value": "ActivePassive", "valueType": "ent:AccountType", "presentation": "Активный/Пассивный" }
]
}
]
}
@@ -123,6 +123,100 @@
</Attribute>
</ChildObjects>
</TabularSection>
<TabularSection uuid="UUID-012">
<InternalInfo>
<xr:GeneratedType name="DataProcessorTabularSection.ДопКолонки.ЕщёТаблица" category="TabularSection">
<xr:TypeId>UUID-013</xr:TypeId>
<xr:ValueId>UUID-014</xr:ValueId>
</xr:GeneratedType>
<xr:GeneratedType name="DataProcessorTabularSectionRow.ДопКолонки.ЕщёТаблица" category="TabularSectionRow">
<xr:TypeId>UUID-015</xr:TypeId>
<xr:ValueId>UUID-016</xr:ValueId>
</xr:GeneratedType>
</InternalInfo>
<Properties>
<Name>ЕщёТаблица</Name>
<Synonym>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Ещё таблица</v8:content>
</v8:item>
</Synonym>
<Comment />
<ToolTip />
<FillChecking>DontCheck</FillChecking>
<StandardAttributes>
<xr:StandardAttribute name="LineNumber">
<xr:LinkByType />
<xr:FillChecking>DontCheck</xr:FillChecking>
<xr:MultiLine>false</xr:MultiLine>
<xr:FillFromFillingValue>false</xr:FillFromFillingValue>
<xr:CreateOnInput>Auto</xr:CreateOnInput>
<xr:MaxValue xsi:nil="true" />
<xr:ToolTip />
<xr:ExtendedEdit>false</xr:ExtendedEdit>
<xr:Format />
<xr:ChoiceForm />
<xr:QuickChoice>Auto</xr:QuickChoice>
<xr:ChoiceHistoryOnInput>Auto</xr:ChoiceHistoryOnInput>
<xr:EditFormat />
<xr:PasswordMode>false</xr:PasswordMode>
<xr:DataHistory>Use</xr:DataHistory>
<xr:MarkNegatives>false</xr:MarkNegatives>
<xr:MinValue xsi:nil="true" />
<xr:Synonym />
<xr:Comment />
<xr:FullTextSearch>Use</xr:FullTextSearch>
<xr:ChoiceParameterLinks />
<xr:FillValue xsi:nil="true" />
<xr:Mask />
<xr:ChoiceParameters />
</xr:StandardAttribute>
</StandardAttributes>
</Properties>
<ChildObjects>
<Attribute uuid="UUID-017">
<Properties>
<Name>Поле</Name>
<Synonym>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Поле</v8:content>
</v8:item>
</Synonym>
<Comment />
<Type>
<v8:Type>xs:string</v8:Type>
<v8:StringQualifiers>
<v8:Length>10</v8:Length>
<v8:AllowedLength>Variable</v8:AllowedLength>
</v8:StringQualifiers>
</Type>
<PasswordMode>false</PasswordMode>
<Format />
<EditFormat />
<ToolTip />
<MarkNegatives>false</MarkNegatives>
<Mask />
<MultiLine>false</MultiLine>
<ExtendedEdit>false</ExtendedEdit>
<MinValue xsi:nil="true" />
<MaxValue xsi:nil="true" />
<FillFromFillingValue>false</FillFromFillingValue>
<FillValue xsi:type="xs:string" />
<FillChecking>DontCheck</FillChecking>
<ChoiceFoldersAndItems>Items</ChoiceFoldersAndItems>
<ChoiceParameterLinks />
<ChoiceParameters />
<QuickChoice>Auto</QuickChoice>
<CreateOnInput>Auto</CreateOnInput>
<ChoiceForm />
<LinkByType />
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
</Properties>
</Attribute>
</ChildObjects>
</TabularSection>
</ChildObjects>
</DataProcessor>
</MetaDataObject>
@@ -43,6 +43,7 @@
</Type>
</Column>
</AdditionalColumns>
<AdditionalColumns table="Объект.ЕщёТаблица"/>
</Columns>
</Attribute>
</Attributes>
@@ -79,6 +79,19 @@
<ContextMenu name="ТаблицаДанныхКартинкаФлагКонтекстноеМеню" id="21"/>
<ExtendedTooltip name="ТаблицаДанныхКартинкаФлагРасширеннаяПодсказка" id="22"/>
</CheckBoxField>
<LabelField name="ТаблицаДанныхИтог" id="23">
<DataPath>ТаблицаДанных.Номенклатура</DataPath>
<EditMode>EnterOnInput</EditMode>
<FooterDataPath>ТаблицаДанных.Номенклатура</FooterDataPath>
<FooterText>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Итого</v8:content>
</v8:item>
</FooterText>
<ContextMenu name="ТаблицаДанныхИтогКонтекстноеМеню" id="24"/>
<ExtendedTooltip name="ТаблицаДанныхИтогРасширеннаяПодсказка" id="25"/>
</LabelField>
</ChildItems>
<Events>
<Event name="Selection">ТаблицаДанныхВыбор</Event>
@@ -86,13 +99,13 @@
</Table>
</ChildItems>
<Attributes>
<Attribute name="Объект" id="23">
<Attribute name="Объект" id="26">
<Type>
<v8:Type>cfg:DataProcessorObject.КартинкаВСтроке</v8:Type>
</Type>
<MainAttribute>true</MainAttribute>
</Attribute>
<Attribute name="ТаблицаДанных" id="24">
<Attribute name="ТаблицаДанных" id="27">
<Title>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -103,7 +116,7 @@
<v8:Type>v8:ValueTable</v8:Type>
</Type>
<Columns>
<Column name="Номенклатура" id="25">
<Column name="Номенклатура" id="28">
<Type>
<v8:Type>xs:string</v8:Type>
<v8:StringQualifiers>
@@ -112,7 +125,7 @@
</v8:StringQualifiers>
</Type>
</Column>
<Column name="Картинка" id="26">
<Column name="Картинка" id="29">
<Type>
<v8:Type>xs:boolean</v8:Type>
</Type>
@@ -11,6 +11,7 @@
<ChildItems>
<RadioButtonField name="ОтборСтрок" id="1">
<DataPath>ОтборСтрок</DataPath>
<EditMode>EnterOnInput</EditMode>
<TitleLocation>None</TitleLocation>
<RadioButtonType>Tumbler</RadioButtonType>
<ChoiceList>
@@ -50,15 +51,68 @@
<ContextMenu name="ОтборСтрокКонтекстноеМеню" id="2"/>
<ExtendedTooltip name="ОтборСтрокРасширеннаяПодсказка" id="3"/>
</RadioButtonField>
<RadioButtonField name="ВидСчета" id="4">
<Title>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Вид счета</v8:content>
</v8:item>
</Title>
<TitleLocation>None</TitleLocation>
<RadioButtonType>Auto</RadioButtonType>
<ChoiceList>
<xr:Item>
<xr:Presentation/>
<xr:CheckState>0</xr:CheckState>
<xr:Value xsi:type="FormChoiceListDesTimeValue">
<Presentation>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Активный</v8:content>
</v8:item>
</Presentation>
<Value xsi:type="ent:AccountType">Active</Value>
</xr:Value>
</xr:Item>
<xr:Item>
<xr:Presentation/>
<xr:CheckState>0</xr:CheckState>
<xr:Value xsi:type="FormChoiceListDesTimeValue">
<Presentation>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Пассивный</v8:content>
</v8:item>
</Presentation>
<Value xsi:type="ent:AccountType">Passive</Value>
</xr:Value>
</xr:Item>
<xr:Item>
<xr:Presentation/>
<xr:CheckState>0</xr:CheckState>
<xr:Value xsi:type="FormChoiceListDesTimeValue">
<Presentation>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Активный/Пассивный</v8:content>
</v8:item>
</Presentation>
<Value xsi:type="ent:AccountType">ActivePassive</Value>
</xr:Value>
</xr:Item>
</ChoiceList>
<ContextMenu name="ВидСчетаКонтекстноеМеню" id="5"/>
<ExtendedTooltip name="ВидСчетаРасширеннаяПодсказка" id="6"/>
</RadioButtonField>
</ChildItems>
<Attributes>
<Attribute name="Объект" id="4">
<Attribute name="Объект" id="7">
<Type>
<v8:Type>cfg:DataProcessorObject.ТестТумблер</v8:Type>
</Type>
<MainAttribute>true</MainAttribute>
</Attribute>
<Attribute name="ОтборСтрок" id="5">
<Attribute name="ОтборСтрок" id="8">
<Title>
<v8:item>
<v8:lang>ru</v8:lang>