mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-09-08 03:00:52 +03:00
fix(meta-edit): формы и макеты отданы form-add/template-add, команда приведена к платформенной
Навык регистрировал форму, макет и команду одинаково — узлом с uuid и <Properties>. Платформа так пишет только команду: форма и макет регистрируются голым текстом (<Form>Имя</Form>) и требуют собственных файлов. В корпусе acc_8.3.24 ни одного <Form uuid и <Template uuid, при 81 голом <Template> и 46 <Command uuid. Подменённая конфигурация валила загрузку с уходом 1cv8 в бесконечное выделение памяти. Форму и макет добавляет form-add / template-add (они делают и файл, и запись), удаляет form-remove / template-remove — meta-edit теперь отсылает к ним вместо тихой порчи. Команда осталась за meta-edit: дописаны CommandParameterType, ParameterUseMode, ModifiesData и OnMainServerUnavalableBehavior, плюс заготовка Commands/<Имя>/Ext/CommandModule.bsl (в корпусе модуль есть у всех 97 команд). Заодно: Table в childOrder, и пустой ChildObjects в PS схлопывается в самозакрывающийся, как его пишет платформа (722 из 722 в корпусе) и py-порт. Проверено платформой 8.3.24.1691: загрузка и обновление успешны, обратная выгрузка даёт узел команды и модуль байт в байт (отличие только в отступе). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NBsZA5cr2WFThtgp7i5WVi
This commit is contained in:
co-authored by
Claude Opus 5
parent
0dac85946f
commit
7dc401718f
@@ -49,7 +49,7 @@ Batch через `;;` во всех операциях. Подробный си
|
||||
| `add-resource` | `Имя: Тип` | `"Сумма: Число(15,2)"` |
|
||||
| `add-enumValue` | `Имя` | `"Значение1 ;; Значение2"` |
|
||||
| `add-column` | `Имя: Тип` | `"Тип: EnumRef.ТипыДокументов"` |
|
||||
| `add-form` / `add-template` / `add-command` | `Имя` | `"ФормаЭлемента"` |
|
||||
| `add-command` | `Имя` | `"ОткрытьДосье"` |
|
||||
| `add-ts-attribute` | `ТЧ.Имя: Тип` | `"Товары.Скидка: Число(15,2)"` |
|
||||
| `remove-*` | `Имя` | `"СтарыйРеквизит ;; ЕщёОдин"` |
|
||||
| `remove-ts-attribute` | `ТЧ.Имя` | `"Товары.УстаревшийРекв"` |
|
||||
@@ -59,6 +59,9 @@ Batch через `;;` во всех операциях. Подробный си
|
||||
|
||||
Позиционная вставка: `"Склад: CatalogRef.Склады >> after Организация"`.
|
||||
|
||||
Форма — `form-add` / `form-remove`, макет — `template-add` / `template-remove`: кроме записи в `ChildObjects`
|
||||
у них есть собственные файлы, и `meta-edit` их не трогает.
|
||||
|
||||
`modify-attribute` умеет и структурные свойства реквизита — формат/подсказку, форму и параметры выбора,
|
||||
значение заполнения, границы (`Format`, `ChoiceForm`, `ChoiceParameters`, `FillValue`, `MinValue`/`MaxValue` и др.).
|
||||
|
||||
|
||||
@@ -133,16 +133,19 @@ JSON — строки и/или объекты (для групп с вложе
|
||||
Ключи объекта: `name`, `code`, `description`, `isFolder`, `childItems` (дерево). Тип кода (строковый/числовой)
|
||||
берётся из объекта автоматически.
|
||||
|
||||
## add-enumValue / add-form / add-template / add-command
|
||||
## add-enumValue / add-command
|
||||
|
||||
Просто имена (batch через `;;`):
|
||||
```powershell
|
||||
-Operation add-enumValue -Value "Значение1 ;; Значение2 ;; Значение3"
|
||||
-Operation add-form -Value "ФормаЭлемента ;; ФормаСписка"
|
||||
-Operation add-template -Value "ПечатнаяФорма"
|
||||
-Operation add-command -Value "Команда1"
|
||||
```
|
||||
|
||||
Команда создаётся вместе с заготовкой модуля `Commands/<Имя>/Ext/CommandModule.bsl`.
|
||||
|
||||
Формы и макеты этот навык не добавляет и не удаляет — у них есть собственные файлы:
|
||||
`form-add` / `form-remove` и `template-add` / `template-remove`.
|
||||
|
||||
## remove-*
|
||||
|
||||
Имя элемента (или несколько через `;;`):
|
||||
|
||||
@@ -22,8 +22,7 @@ powershell.exe -NoProfile -File ${CLAUDE_SKILL_DIR}/scripts/meta-edit.ps1 -Defin
|
||||
{ "name": "Количество", "type": "Число(15,3)" }
|
||||
]
|
||||
}],
|
||||
"forms": ["ФормаЭлемента"],
|
||||
"templates": ["ПечатнаяФорма"]
|
||||
"commands": ["Пересчитать"]
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -120,6 +119,9 @@ powershell.exe -NoProfile -File ${CLAUDE_SKILL_DIR}/scripts/meta-edit.ps1 -Defin
|
||||
| commands | команды |
|
||||
| properties | свойства |
|
||||
|
||||
Формы и макеты `meta-edit` не добавляет и не удаляет: кроме записи в `ChildObjects` у них есть собственные файлы.
|
||||
Форма — `form-add` / `form-remove`, макет — `template-add` / `template-remove`. Команда файла не имеет — её `meta-edit` добавляет сам.
|
||||
|
||||
## Составные типы
|
||||
|
||||
Для полей с несколькими допустимыми типами — массив в `type`:
|
||||
@@ -141,8 +143,11 @@ powershell.exe -NoProfile -File ${CLAUDE_SKILL_DIR}/scripts/meta-edit.ps1 -Defin
|
||||
|
||||
| Тип объекта | Допустимые add-типы |
|
||||
|-------------|-------------------|
|
||||
| Catalog, Document, ExchangePlan, ChartOf*, BP, Task, Report, DP | attributes, tabularSections, forms, templates, commands |
|
||||
| Enum | enumValues, forms, templates, commands |
|
||||
| *Register (4 типа) | dimensions, resources, attributes, forms, templates, commands |
|
||||
| DocumentJournal | columns, forms, templates, commands |
|
||||
| Constant | forms |
|
||||
| Catalog, Document, ExchangePlan, ChartOf*, BP, Task, Report, DP | attributes, tabularSections, commands |
|
||||
| Enum | enumValues, commands |
|
||||
| *Register (4 типа) | dimensions, resources, attributes, commands |
|
||||
| DocumentJournal | columns, commands |
|
||||
| ExternalDataSource | tables, functions |
|
||||
| Table (таблица внешнего источника) | fields, commands |
|
||||
|
||||
У `Constant` добавлять нечего: единственный её ребёнок — форма, а форму добавляет `form-add`.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# meta-edit v1.47 — Edit existing 1C metadata object XML
|
||||
# meta-edit v1.48 — Edit existing 1C metadata object XML
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
[CmdletBinding(PositionalBinding=$false)]
|
||||
param(
|
||||
@@ -904,6 +904,9 @@ function Collapse-ChildObjectsIfEmpty {
|
||||
while ($script:childObjectsEl.HasChildNodes) {
|
||||
$script:childObjectsEl.RemoveChild($script:childObjectsEl.FirstChild) | Out-Null
|
||||
}
|
||||
# XmlDocument помнит, что у узла были дети, и пишет <ChildObjects></ChildObjects>.
|
||||
# Платформа и py-порт дают <ChildObjects/> — сбрасываем флаг явно.
|
||||
$script:childObjectsEl.IsEmpty = $true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1458,35 +1461,29 @@ function Build-ColumnFragment {
|
||||
return $sb.ToString()
|
||||
}
|
||||
|
||||
function Build-SimpleChildFragment {
|
||||
param([string]$tagName, [string]$name, [string]$indent)
|
||||
# For Form, Template, Command — just a name wrapper
|
||||
function Build-CommandFragment {
|
||||
param([string]$name, [string]$indent)
|
||||
# Команда объекта описывается целиком внутри ChildObjects (отдельного файла у неё нет).
|
||||
# Порядок свойств платформенный — переставлять нельзя.
|
||||
$uuid = New-Guid-String
|
||||
$synonym = Split-CamelCase $name
|
||||
$sb = New-Object System.Text.StringBuilder
|
||||
$sb.AppendLine("$indent<$tagName uuid=`"$uuid`">") | Out-Null
|
||||
$sb.AppendLine("$indent<Command uuid=`"$uuid`">") | Out-Null
|
||||
$sb.AppendLine("$indent`t<Properties>") | Out-Null
|
||||
$sb.AppendLine("$indent`t`t<Name>$(Esc-XmlText $name)</Name>") | Out-Null
|
||||
$sb.AppendLine($(Build-MLTextXml "$indent`t`t" "Synonym" $synonym)) | Out-Null
|
||||
$sb.AppendLine("$indent`t`t<Comment/>") | Out-Null
|
||||
# Forms get additional properties
|
||||
if ($tagName -eq "Form") {
|
||||
$sb.AppendLine("$indent`t`t<FormType>Ordinary</FormType>") | Out-Null
|
||||
$sb.AppendLine("$indent`t`t<IncludeHelpInContents>false</IncludeHelpInContents>") | Out-Null
|
||||
$sb.AppendLine("$indent`t`t<UsePurposes/>") | Out-Null
|
||||
}
|
||||
if ($tagName -eq "Template") {
|
||||
$sb.AppendLine("$indent`t`t<TemplateType>SpreadsheetDocument</TemplateType>") | Out-Null
|
||||
}
|
||||
if ($tagName -eq "Command") {
|
||||
$sb.AppendLine("$indent`t`t<Group>FormNavigationPanelGoTo</Group>") | Out-Null
|
||||
$sb.AppendLine("$indent`t`t<Representation>Auto</Representation>") | Out-Null
|
||||
$sb.AppendLine("$indent`t`t<ToolTip/>") | Out-Null
|
||||
$sb.AppendLine("$indent`t`t<Picture/>") | Out-Null
|
||||
$sb.AppendLine("$indent`t`t<Shortcut/>") | Out-Null
|
||||
}
|
||||
$sb.AppendLine("$indent`t`t<Group>FormNavigationPanelGoTo</Group>") | Out-Null
|
||||
$sb.AppendLine("$indent`t`t<CommandParameterType/>") | Out-Null
|
||||
$sb.AppendLine("$indent`t`t<ParameterUseMode>Single</ParameterUseMode>") | Out-Null
|
||||
$sb.AppendLine("$indent`t`t<ModifiesData>false</ModifiesData>") | Out-Null
|
||||
$sb.AppendLine("$indent`t`t<Representation>Auto</Representation>") | Out-Null
|
||||
$sb.AppendLine("$indent`t`t<ToolTip/>") | Out-Null
|
||||
$sb.AppendLine("$indent`t`t<Picture/>") | Out-Null
|
||||
$sb.AppendLine("$indent`t`t<Shortcut/>") | Out-Null
|
||||
$sb.AppendLine("$indent`t`t<OnMainServerUnavalableBehavior>Auto</OnMainServerUnavalableBehavior>") | Out-Null
|
||||
$sb.AppendLine("$indent`t</Properties>") | Out-Null
|
||||
$sb.Append("$indent</$tagName>") | Out-Null
|
||||
$sb.Append("$indent</Command>") | Out-Null
|
||||
return $sb.ToString()
|
||||
}
|
||||
|
||||
@@ -1576,7 +1573,7 @@ $script:validChildTypes = @{
|
||||
|
||||
# Canonical child order in ChildObjects
|
||||
$script:childOrder = @(
|
||||
"Resource", "Dimension", "Attribute", "TabularSection", "Field", "Function",
|
||||
"Resource", "Dimension", "Attribute", "TabularSection", "Field", "Table", "Function",
|
||||
"AccountingFlag", "ExtDimensionAccountingFlag",
|
||||
"EnumValue", "Column", "AddressingAttribute", "Recalculation",
|
||||
"Form", "Template", "Command"
|
||||
@@ -2421,24 +2418,36 @@ function Process-Add($addDef) {
|
||||
$existingNames[$colName] = "Column"
|
||||
}
|
||||
}
|
||||
{ $_ -in @("forms","templates","commands") } {
|
||||
$tagMap = @{ "forms" = "Form"; "templates" = "Template"; "commands" = "Command" }
|
||||
$tag = $tagMap[$childType]
|
||||
{ $_ -in @("forms","templates") } {
|
||||
# Форма и макет регистрируются голым текстом (<Form>Имя</Form>) и требуют ещё и
|
||||
# собственных файлов. И то и другое делают form-add / template-add — дублировать
|
||||
# эту ответственность здесь нельзя: получится висячая регистрация без файла.
|
||||
$skillName = if ($childType -eq "forms") { "form-add" } else { "template-add" }
|
||||
$whatName = if ($childType -eq "forms") { "Форму" } else { "Макет" }
|
||||
Warn "$whatName добавляет навык $skillName (он создаёт и файл, и запись в ChildObjects). meta-edit этого не делает — операция пропущена."
|
||||
}
|
||||
"commands" {
|
||||
foreach ($item in $items) {
|
||||
$itemName = if ($item -is [string]) { "$item" } else { "$($item.name)" }
|
||||
if ($existingNames.ContainsKey($itemName)) {
|
||||
Warn "$tag '$itemName' already exists, skipping"
|
||||
Warn "Command '$itemName' already exists, skipping"
|
||||
continue
|
||||
}
|
||||
$fragmentXml = Build-SimpleChildFragment $tag $itemName $indent
|
||||
# У команды есть модуль обработчика (Commands/<Имя>/Ext/CommandModule.bsl) — в корпусе
|
||||
# он есть у всех команд без исключения. Пишем ту же заготовку, что и meta-compile.
|
||||
$cmdExtDir = Join-Path (Join-Path (Join-Path (Join-Path (Split-Path -Parent $resolvedPath) $script:objName) "Commands") $itemName) "Ext"
|
||||
$cmdModPath = Join-Path $cmdExtDir "CommandModule.bsl"
|
||||
if (-not (Test-Path $cmdExtDir)) { New-Item -ItemType Directory -Path $cmdExtDir -Force | Out-Null }
|
||||
[System.IO.File]::WriteAllText($cmdModPath, "&НаКлиенте`r`nПроцедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)`r`n`r`n`t// Вставьте обработчик команды.`r`n`r`nКонецПроцедуры`r`n", (New-Object System.Text.UTF8Encoding($true)))
|
||||
$fragmentXml = Build-CommandFragment $itemName $indent
|
||||
$nodes = Import-Fragment $fragmentXml
|
||||
$refNode = Find-InsertionPoint $tag @{ after = ""; before = "" }
|
||||
$refNode = Find-InsertionPoint "Command" @{ after = ""; before = "" }
|
||||
foreach ($node in $nodes) {
|
||||
Insert-BeforeElement $script:childObjectsEl $node $refNode $indent
|
||||
}
|
||||
Info "Added $($tag.ToLower()): $itemName"
|
||||
Info "Added command: $itemName ($cmdModPath)"
|
||||
$script:addCount++
|
||||
$existingNames[$itemName] = $tag
|
||||
$existingNames[$itemName] = "Command"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2463,6 +2472,13 @@ function Process-Remove($removeDef) {
|
||||
Warn "Cannot remove properties — use modify instead"
|
||||
return
|
||||
}
|
||||
if ($childType -in @("forms","templates")) {
|
||||
# Снять регистрацию мало — надо удалить и файлы; это делают form-remove / template-remove.
|
||||
$skillName = if ($childType -eq "forms") { "form-remove" } else { "template-remove" }
|
||||
$whatName = if ($childType -eq "forms") { "Форму" } else { "Макет" }
|
||||
Warn "$whatName удаляет навык $skillName (он убирает и файлы, и запись в ChildObjects). meta-edit этого не делает — операция пропущена."
|
||||
return
|
||||
}
|
||||
|
||||
$xmlTag = $script:childTypeToXmlTag[$childType]
|
||||
if (-not $xmlTag -or -not $script:childObjectsEl) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# meta-edit v1.47 — Edit existing 1C metadata object XML
|
||||
# meta-edit v1.48 — Edit existing 1C metadata object XML
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -1478,34 +1478,32 @@ def build_column_fragment(col_def, indent):
|
||||
return "\r\n".join(lines)
|
||||
|
||||
|
||||
def build_simple_child_fragment(tag_name, name, indent):
|
||||
"""Build XML fragment for Form, Template, Command -- just a name wrapper."""
|
||||
def build_command_fragment(name, indent):
|
||||
"""Build XML fragment for a Command (it has no separate file -- all inline).
|
||||
|
||||
Property order is the platform's -- do not reorder.
|
||||
"""
|
||||
uid = new_uuid()
|
||||
synonym = split_camel_case(name)
|
||||
lines = []
|
||||
lines.append(f'{indent}<{tag_name} uuid="{uid}">')
|
||||
lines.append(f'{indent}<Command uuid="{uid}">')
|
||||
lines.append(f"{indent}\t<Properties>")
|
||||
lines.append(f"{indent}\t\t<Name>{esc_xml_text(name)}</Name>")
|
||||
lines.append(build_mltext_xml(f"{indent}\t\t", "Synonym", synonym))
|
||||
lines.append(f"{indent}\t\t<Comment/>")
|
||||
# Forms get additional properties
|
||||
if tag_name == "Form":
|
||||
lines.append(f"{indent}\t\t<FormType>Ordinary</FormType>")
|
||||
lines.append(f"{indent}\t\t<IncludeHelpInContents>false</IncludeHelpInContents>")
|
||||
lines.append(f"{indent}\t\t<UsePurposes/>")
|
||||
if tag_name == "Template":
|
||||
lines.append(f"{indent}\t\t<TemplateType>SpreadsheetDocument</TemplateType>")
|
||||
if tag_name == "Command":
|
||||
lines.append(f"{indent}\t\t<Group>FormNavigationPanelGoTo</Group>")
|
||||
lines.append(f"{indent}\t\t<Representation>Auto</Representation>")
|
||||
lines.append(f"{indent}\t\t<ToolTip/>")
|
||||
lines.append(f"{indent}\t\t<Picture/>")
|
||||
lines.append(f"{indent}\t\t<Shortcut/>")
|
||||
lines.append(f"{indent}\t\t<Group>FormNavigationPanelGoTo</Group>")
|
||||
lines.append(f"{indent}\t\t<CommandParameterType/>")
|
||||
lines.append(f"{indent}\t\t<ParameterUseMode>Single</ParameterUseMode>")
|
||||
lines.append(f"{indent}\t\t<ModifiesData>false</ModifiesData>")
|
||||
lines.append(f"{indent}\t\t<Representation>Auto</Representation>")
|
||||
lines.append(f"{indent}\t\t<ToolTip/>")
|
||||
lines.append(f"{indent}\t\t<Picture/>")
|
||||
lines.append(f"{indent}\t\t<Shortcut/>")
|
||||
lines.append(f"{indent}\t\t<OnMainServerUnavalableBehavior>Auto</OnMainServerUnavalableBehavior>")
|
||||
lines.append(f"{indent}\t</Properties>")
|
||||
lines.append(f"{indent}</{tag_name}>")
|
||||
lines.append(f"{indent}</Command>")
|
||||
return "\r\n".join(lines)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Name uniqueness check
|
||||
# ============================================================
|
||||
@@ -1567,7 +1565,7 @@ valid_child_types = {
|
||||
|
||||
# Canonical child order in ChildObjects
|
||||
child_order = [
|
||||
"Resource", "Dimension", "Attribute", "TabularSection", "Field", "Function",
|
||||
"Resource", "Dimension", "Attribute", "TabularSection", "Field", "Table", "Function",
|
||||
"AccountingFlag", "ExtDimensionAccountingFlag",
|
||||
"EnumValue", "Column", "AddressingAttribute", "Recalculation",
|
||||
"Form", "Template", "Command",
|
||||
@@ -2350,26 +2348,42 @@ def process_add(add_def):
|
||||
add_count += 1
|
||||
existing_names[col_name] = "Column"
|
||||
|
||||
elif child_type in ("forms", "templates", "commands"):
|
||||
tag_map = {"forms": "Form", "templates": "Template", "commands": "Command"}
|
||||
tag = tag_map[child_type]
|
||||
elif child_type in ("forms", "templates"):
|
||||
# Форма и макет регистрируются голым текстом (<Form>Имя</Form>) и требуют ещё и
|
||||
# собственных файлов. И то и другое делают form-add / template-add -- дублировать
|
||||
# эту ответственность здесь нельзя: получится висячая регистрация без файла.
|
||||
skill_name = "form-add" if child_type == "forms" else "template-add"
|
||||
what_name = "Форму" if child_type == "forms" else "Макет"
|
||||
warn(
|
||||
f"{what_name} добавляет навык {skill_name} "
|
||||
"(он создаёт и файл, и запись в ChildObjects). "
|
||||
"meta-edit этого не делает — операция пропущена."
|
||||
)
|
||||
|
||||
elif child_type == "commands":
|
||||
for item in items:
|
||||
if isinstance(item, str):
|
||||
item_name = item
|
||||
else:
|
||||
item_name = str(item.get("name", ""))
|
||||
if item_name in existing_names:
|
||||
warn(f"{tag} '{item_name}' already exists, skipping")
|
||||
warn(f"Command '{item_name}' already exists, skipping")
|
||||
continue
|
||||
fragment_xml = build_simple_child_fragment(tag, item_name, indent)
|
||||
# У команды есть модуль обработчика (Commands/<Имя>/Ext/CommandModule.bsl) — в корпусе
|
||||
# он есть у всех команд без исключения. Пишем ту же заготовку, что и meta-compile.
|
||||
cmd_ext_dir = os.path.join(os.path.dirname(resolved_path), obj_name, "Commands", item_name, "Ext")
|
||||
cmd_mod_path = os.path.join(cmd_ext_dir, "CommandModule.bsl")
|
||||
os.makedirs(cmd_ext_dir, exist_ok=True)
|
||||
with open(cmd_mod_path, "w", encoding="utf-8-sig", newline="") as fh:
|
||||
fh.write("&НаКлиенте\r\nПроцедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)\r\n\r\n\t// Вставьте обработчик команды.\r\n\r\nКонецПроцедуры\r\n")
|
||||
fragment_xml = build_command_fragment(item_name, indent)
|
||||
nodes = import_fragment(fragment_xml)
|
||||
ref_node = find_insertion_point(tag, {"after": "", "before": ""})
|
||||
ref_node = find_insertion_point("Command", {"after": "", "before": ""})
|
||||
for node in nodes:
|
||||
insert_before_element(child_objects_el, node, ref_node, indent)
|
||||
info(f"Added {tag.lower()}: {item_name}")
|
||||
info(f"Added command: {item_name} ({cmd_mod_path})")
|
||||
add_count += 1
|
||||
existing_names[item_name] = tag
|
||||
|
||||
existing_names[item_name] = "Command"
|
||||
|
||||
# ============================================================
|
||||
# REMOVE operations
|
||||
@@ -2388,6 +2402,16 @@ def process_remove(remove_def):
|
||||
if child_type == "properties":
|
||||
warn("Cannot remove properties -- use modify instead")
|
||||
continue
|
||||
if child_type in ("forms", "templates"):
|
||||
# Снять регистрацию мало — надо удалить и файлы; это делают form-remove / template-remove.
|
||||
skill_name = "form-remove" if child_type == "forms" else "template-remove"
|
||||
what_name = "Форму" if child_type == "forms" else "Макет"
|
||||
warn(
|
||||
f"{what_name} удаляет навык {skill_name} "
|
||||
"(он убирает и файлы, и запись в ChildObjects). "
|
||||
"meta-edit этого не делает — операция пропущена."
|
||||
)
|
||||
continue
|
||||
|
||||
xml_tag = child_type_to_xml_tag.get(child_type)
|
||||
if not xml_tag or child_objects_el is None:
|
||||
|
||||
Reference in New Issue
Block a user