@amaster.ai/pi-lark 0.1.7 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/skills/lark-apps/SKILL.md +41 -6
- package/skills/lark-apps/references/lark-apps-cloud-dev.md +5 -4
- package/skills/lark-apps/references/lark-apps-create.md +6 -3
- package/skills/lark-apps/references/lark-apps-db.md +130 -2
- package/skills/lark-apps/references/lark-apps-get.md +1 -1
- package/skills/lark-apps/references/lark-apps-list.md +1 -1
- package/skills/lark-apps/references/lark-apps-local-dev.md +27 -1
- package/skills/lark-apps/references/lark-apps-release-create.md +1 -1
- package/skills/lark-apps/references/lark-apps-user-id-convert.md +63 -0
- package/skills/lark-base/SKILL.md +155 -159
- package/skills/lark-base/references/{lark-base-role-guide.md → lark-base-advanced-permission-and-role.md} +5 -5
- package/skills/lark-base/references/lark-base-app-block-data-config.md +122 -0
- package/skills/lark-base/references/lark-base-app.md +225 -0
- package/skills/lark-base/references/lark-base-cell-value.md +26 -19
- package/skills/lark-base/references/{dashboard-block-data-config.md → lark-base-dashboard-block-config.md} +37 -5
- package/skills/lark-base/references/lark-base-dashboard-block-get-data.md +18 -2
- package/skills/lark-base/references/lark-base-dashboard.md +25 -12
- package/skills/lark-base/references/lark-base-data-analysis-pandas.md +93 -0
- package/skills/lark-base/references/lark-base-data-analysis-python-stdlib.md +120 -0
- package/skills/lark-base/references/lark-base-data-query.md +8 -11
- package/skills/lark-base/references/lark-base-field-create.md +13 -45
- package/skills/lark-base/references/{formula-field-guide.md → lark-base-field-formula.md} +1 -1
- package/skills/lark-base/references/{lookup-field-guide.md → lark-base-field-lookup.md} +1 -1
- package/skills/lark-base/references/{lark-base-field-json.md → lark-base-field-schema.md} +18 -100
- package/skills/lark-base/references/lark-base-field-update.md +13 -51
- package/skills/lark-base/references/lark-base-filter-condition.md +19 -31
- package/skills/lark-base/references/lark-base-record-batch-create.md +5 -1
- package/skills/lark-base/references/lark-base-record-batch-update.md +5 -2
- package/skills/lark-base/references/lark-base-record-query-and-analysis-cloud-sop.md +145 -0
- package/skills/lark-base/references/lark-base-record-query-and-analysis-sop.md +233 -0
- package/skills/lark-base/references/{role-config.md → lark-base-role-config.md} +2 -2
- package/skills/lark-base/references/lark-base-view-set-filter.md +1 -1
- package/skills/lark-base/references/lark-base-workflow-schema.md +2 -2
- package/skills/lark-base/references/{lark-base-workflow-guide.md → lark-base-workflow.md} +1 -1
- package/skills/lark-calendar/SKILL.md +3 -1
- package/skills/lark-calendar/references/lark-calendar-create.md +4 -3
- package/skills/lark-doc/SKILL.md +26 -61
- package/skills/lark-doc/references/genres/business-analysis.md +30 -0
- package/skills/lark-doc/references/genres/data-report.md +32 -0
- package/skills/lark-doc/references/genres/email.md +38 -0
- package/skills/lark-doc/references/genres/execution-plan.md +27 -0
- package/skills/lark-doc/references/genres/formal-doc.md +37 -0
- package/skills/lark-doc/references/genres/meeting-minutes.md +24 -0
- package/skills/lark-doc/references/genres/memo-brief.md +25 -0
- package/skills/lark-doc/references/genres/official-redhead.md +73 -0
- package/skills/lark-doc/references/genres/prd.md +26 -0
- package/skills/lark-doc/references/genres/proposal.md +24 -0
- package/skills/lark-doc/references/genres/research-report.md +32 -0
- package/skills/lark-doc/references/genres/retrospective.md +25 -0
- package/skills/lark-doc/references/genres/route-consumer.md +37 -0
- package/skills/lark-doc/references/genres/route-creative.md +36 -0
- package/skills/lark-doc/references/genres/route-knowledge.md +39 -0
- package/skills/lark-doc/references/genres/route-marketing.md +40 -0
- package/skills/lark-doc/references/genres/route-media.md +36 -0
- package/skills/lark-doc/references/genres/route-opinion.md +38 -0
- package/skills/lark-doc/references/genres/route-personal-brand.md +36 -0
- package/skills/lark-doc/references/genres/route-platform.md +9 -0
- package/skills/lark-doc/references/genres/route-report.md +10 -0
- package/skills/lark-doc/references/genres/route-workplace.md +17 -0
- package/skills/lark-doc/references/genres/sop-tutorial.md +41 -0
- package/skills/lark-doc/references/genres/technical-doc.md +39 -0
- package/skills/lark-doc/references/genres/wechat.md +39 -0
- package/skills/lark-doc/references/genres/weekly-report.md +24 -0
- package/skills/lark-doc/references/genres/white-paper.md +32 -0
- package/skills/lark-doc/references/genres/xiaohongshu.md +38 -0
- package/skills/lark-doc/references/lark-doc-create-workflow.md +121 -0
- package/skills/lark-doc/references/lark-doc-create.md +22 -48
- package/skills/lark-doc/references/lark-doc-fetch.md +80 -92
- package/skills/lark-doc/references/lark-doc-history.md +16 -15
- package/skills/lark-doc/references/lark-doc-md.md +5 -1
- package/skills/lark-doc/references/lark-doc-media-download.md +2 -1
- package/skills/lark-doc/references/lark-doc-script.md +76 -0
- package/skills/lark-doc/references/lark-doc-update.md +73 -221
- package/skills/lark-doc/references/lark-doc-whiteboard.md +5 -9
- package/skills/lark-doc/references/lark-doc-xml-extended-blocks.md +17 -12
- package/skills/lark-doc/references/lark-doc-xml.md +38 -167
- package/skills/lark-drive/SKILL.md +11 -7
- package/skills/lark-drive/references/lark-drive-apply-permission.md +1 -1
- package/skills/lark-drive/references/lark-drive-copy.md +87 -0
- package/skills/lark-drive/references/lark-drive-download.md +29 -2
- package/skills/lark-drive/references/lark-drive-export.md +4 -0
- package/skills/lark-drive/references/lark-drive-member-remove.md +59 -0
- package/skills/lark-drive/references/lark-drive-preview.md +21 -2
- package/skills/lark-drive/references/lark-drive-push.md +5 -1
- package/skills/lark-drive/references/lark-drive-search.md +2 -0
- package/skills/lark-drive/references/lark-drive-task-result.md +3 -0
- package/skills/lark-drive/references/lark-drive-update-title.md +78 -0
- package/skills/lark-event/SKILL.md +7 -4
- package/skills/lark-event/references/lark-event-vc.md +8 -2
- package/skills/lark-im/SKILL.md +14 -9
- package/skills/lark-im/references/lark-im-chat-list.md +9 -2
- package/skills/lark-im/references/lark-im-chat-members-list.md +7 -4
- package/skills/lark-im/references/lark-im-chat-messages-list.md +10 -3
- package/skills/lark-im/references/lark-im-chat-search.md +9 -2
- package/skills/lark-im/references/lark-im-feed-group-list-item.md +2 -2
- package/skills/lark-im/references/lark-im-feed-group-list.md +2 -2
- package/skills/lark-im/references/lark-im-feed-shortcut-list.md +1 -1
- package/skills/lark-im/references/lark-im-flag-list.md +2 -2
- package/skills/lark-im/references/lark-im-message-enrichment.md +1 -1
- package/skills/lark-im/references/lark-im-messages-resources-download.md +19 -25
- package/skills/lark-im/references/lark-im-messages-search.md +4 -5
- package/skills/lark-im/references/lark-im-threads-messages-list.md +8 -4
- package/skills/lark-mail/references/lark-mail-triage.md +19 -4
- package/skills/lark-minutes/SKILL.md +12 -6
- package/skills/lark-minutes/references/lark-minutes-apply-permission.md +95 -0
- package/skills/lark-minutes/references/lark-minutes-detail.md +7 -6
- package/skills/lark-minutes/references/lark-minutes-download.md +4 -2
- package/skills/lark-minutes/references/lark-minutes-search.md +6 -7
- package/skills/lark-note/SKILL.md +13 -9
- package/skills/lark-note/references/lark-note-detail.md +5 -2
- package/skills/lark-note/references/lark-note-transcript.md +2 -0
- package/skills/lark-shared/SKILL.md +39 -3
- package/skills/lark-sheets/SKILL.md +83 -82
- package/skills/lark-sheets/references/lark-sheets-batch-update.md +13 -58
- package/skills/lark-sheets/references/lark-sheets-chart.md +2 -1
- package/skills/lark-sheets/references/lark-sheets-conditional-format.md +1 -1
- package/skills/lark-sheets/references/lark-sheets-range-operations.md +5 -5
- package/skills/lark-sheets/references/lark-sheets-read-data.md +80 -6
- package/skills/lark-sheets/references/lark-sheets-sheet-structure.md +21 -10
- package/skills/lark-sheets/references/lark-sheets-styles-put.md +93 -0
- package/skills/lark-sheets/references/lark-sheets-visual-standards.md +2 -2
- package/skills/lark-sheets/references/lark-sheets-workbook.md +4 -3
- package/skills/lark-sheets/references/lark-sheets-write-cells.md +40 -12
- package/skills/lark-sheets/scripts/lark_detect_subtables.py +593 -0
- package/skills/lark-sheets/scripts/lark_inspect_workbook.py +188 -0
- package/skills/lark-sheets/scripts/lark_profile_table.py +614 -0
- package/skills/lark-sheets/scripts/lark_sheet_range.py +176 -0
- package/skills/lark-sheets/scripts/lark_sheet_read_cli.py +184 -0
- package/skills/lark-sheets/scripts/sheets_df.py +21 -3
- package/skills/lark-slides/SKILL.md +64 -81
- package/skills/lark-slides/references/cli/lark-slides-add-slide.md +92 -0
- package/skills/lark-slides/references/cli/lark-slides-create.md +176 -0
- package/skills/lark-slides/references/cli/lark-slides-delete-slide.md +65 -0
- package/skills/lark-slides/references/cli/lark-slides-history.md +132 -0
- package/skills/lark-slides/references/cli/lark-slides-media-upload.md +103 -0
- package/skills/lark-slides/references/cli/lark-slides-replace-slide.md +259 -0
- package/skills/lark-slides/references/cli/lark-slides-screenshot.md +115 -0
- package/skills/lark-slides/references/cli/lark-slides-update-slide.md +163 -0
- package/skills/lark-slides/references/cli/lark-slides-xml-presentation-slide-get.md +110 -0
- package/skills/lark-slides/references/cli/lark-slides-xml-presentation-slide-replace.md +188 -0
- package/skills/lark-slides/references/cli/lark-slides-xml-presentations-get.md +157 -0
- package/skills/lark-slides/references/iconpark-index.json +5 -41901
- package/skills/lark-slides/references/iconpark.md +3 -44
- package/skills/lark-slides/references/lark-slides-add-slide.md +5 -0
- package/skills/lark-slides/references/lark-slides-create.md +3 -162
- package/skills/lark-slides/references/lark-slides-delete-slide.md +5 -0
- package/skills/lark-slides/references/lark-slides-edit-workflows.md +3 -142
- package/skills/lark-slides/references/lark-slides-history.md +3 -130
- package/skills/lark-slides/references/lark-slides-media-upload.md +3 -124
- package/skills/lark-slides/references/lark-slides-pptx-template-workflows.md +3 -83
- package/skills/lark-slides/references/lark-slides-replace-slide.md +3 -235
- package/skills/lark-slides/references/lark-slides-screenshot.md +3 -95
- package/skills/lark-slides/references/lark-slides-xml-presentation-slide-get.md +3 -108
- package/skills/lark-slides/references/lark-slides-xml-presentation-slide-replace.md +3 -186
- package/skills/lark-slides/references/lark-slides-xml-presentations-get.md +3 -132
- package/skills/lark-slides/references/planning-layer.md +1 -1
- package/skills/lark-slides/references/slides_chart_demo.xml +5 -1416
- package/skills/lark-slides/references/slides_xml_schema_definition.xml +3 -3468
- package/skills/lark-slides/references/troubleshooting.md +3 -61
- package/skills/lark-slides/references/validation-checklist.md +3 -154
- package/skills/lark-slides/references/workflow/error-handling.md +62 -0
- package/skills/lark-slides/references/workflow/slides-editing.md +143 -0
- package/skills/lark-slides/references/workflow/template-editing.md +85 -0
- package/skills/lark-slides/references/workflow/validation-xml.md +156 -0
- package/skills/lark-slides/references/xml/iconpark-index.json +37458 -0
- package/skills/lark-slides/references/xml/iconpark.md +46 -0
- package/skills/lark-slides/references/xml/slides_chart_demo.xml +1415 -0
- package/skills/lark-slides/references/xml/slides_xml_schema_definition.xml +3514 -0
- package/skills/lark-slides/references/xml/xml-schema-quick-ref.md +497 -0
- package/skills/lark-slides/references/xml-schema-quick-ref.md +3 -483
- package/skills/lark-slides/scripts/iconpark_tool.py +1 -1
- package/skills/lark-slides/scripts/sxsd_validator.py +154 -10
- package/skills/lark-slides/scripts/xml_lint.py +2989 -0
- package/skills/lark-slides/scripts/xml_lint_test.py +4720 -0
- package/skills/lark-slides/scripts/xml_text_overlap_lint.py +3 -2691
- package/skills/lark-slides/scripts/xml_text_overlap_lint_test.py +5 -3788
- package/skills/lark-task/SKILL.md +12 -0
- package/skills/lark-task/references/lark-task-create.md +3 -1
- package/skills/lark-vc/SKILL.md +15 -5
- package/skills/lark-vc/references/lark-vc-detail.md +11 -6
- package/skills/{lark-vc-agent/references/lark-vc-agent-meeting-events.md → lark-vc/references/lark-vc-meeting-events.md} +121 -20
- package/skills/{lark-vc-agent/references/lark-vc-agent-meeting-list-active.md → lark-vc/references/lark-vc-meeting-list-active.md} +2 -2
- package/skills/{lark-vc-agent/references/lark-vc-agent-meeting-message-send.md → lark-vc/references/lark-vc-meeting-message-send.md} +3 -3
- package/skills/lark-vc/references/lark-vc-recording.md +8 -6
- package/skills/lark-vc/references/vc-domain-boundaries.md +8 -1
- package/skills/lark-vc-agent/SKILL.md +24 -9
- package/skills/lark-vc-agent/references/lark-vc-agent-meeting-join.md +2 -2
- package/skills/lark-vc-agent/references/lark-vc-agent-meeting-leave.md +2 -2
- package/skills/lark-whiteboard/SKILL.md +15 -8
- package/skills/lark-whiteboard/references/lark-whiteboard-export.md +4 -3
- package/skills/lark-whiteboard/references/lark-whiteboard-update.md +4 -4
- package/skills/lark-whiteboard/references/lark-whiteboard-workflow.md +19 -17
- package/skills/lark-whiteboard/routes/dsl.md +8 -2
- package/skills/lark-whiteboard/routes/mermaid.md +1 -1
- package/skills/lark-whiteboard/routes/svg-edit.md +5 -2
- package/skills/lark-whiteboard/routes/svg.md +3 -1
- package/skills/lark-whiteboard/scenes/mention.md +71 -0
- package/skills/lark-wiki/SKILL.md +8 -4
- package/skills/lark-wiki/references/lark-wiki-delete-space.md +6 -3
- package/skills/lark-wiki/references/lark-wiki-node-copy.md +5 -19
- package/skills/lark-wiki/references/lark-wiki-node-create.md +19 -2
- package/skills/lark-wiki/references/lark-wiki-node-get.md +15 -0
- package/skills/lark-wiki/references/lark-wiki-node-list.md +1 -1
- package/skills/lark-base/references/lark-base-data-analysis-sop.md +0 -210
- package/skills/lark-base/references/lark-base-data-query-guide.md +0 -61
- package/skills/lark-base/references/lark-base-record-upsert.md +0 -63
- package/skills/lark-doc/references/lark-doc-word-stat.md +0 -93
- package/skills/lark-doc/references/style/lark-doc-create-workflow.md +0 -47
- package/skills/lark-doc/references/style/lark-doc-style.md +0 -68
- package/skills/lark-doc/references/style/lark-doc-update-workflow.md +0 -48
- package/skills/lark-doc/scripts/doc_word_stat.py +0 -1243
- package/skills/lark-slides/references/lark-slides-replace-pages.md +0 -95
- package/skills/lark-slides/references/lark-slides-xml-presentation-slide-create.md +0 -219
- package/skills/lark-slides/references/lark-slides-xml-presentation-slide-delete.md +0 -126
|
@@ -16,11 +16,11 @@ from typing import Any
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
XS_NS = "{http://www.w3.org/2001/XMLSchema}"
|
|
19
|
-
SML_NAMESPACE = "
|
|
19
|
+
SML_NAMESPACE = "https://www.larkoffice.com/sml/2.0"
|
|
20
|
+
SML_LEGACY_HTTP_NAMESPACE = "http://www.larkoffice.com/sml/2.0"
|
|
20
21
|
SML_READBACK_NAMESPACE = "/sml/2.0"
|
|
21
|
-
SML_HTTPS_READBACK_NAMESPACE = "https://www.larkoffice.com/sml/2.0"
|
|
22
22
|
ACCEPTED_SML_NAMESPACES = frozenset(
|
|
23
|
-
(SML_NAMESPACE,
|
|
23
|
+
(SML_NAMESPACE, SML_LEGACY_HTTP_NAMESPACE, SML_READBACK_NAMESPACE)
|
|
24
24
|
)
|
|
25
25
|
|
|
26
26
|
|
|
@@ -79,6 +79,15 @@ class ChildRule:
|
|
|
79
79
|
order: int | None
|
|
80
80
|
|
|
81
81
|
|
|
82
|
+
@dataclass(frozen=True)
|
|
83
|
+
class WildcardRule:
|
|
84
|
+
namespace: str
|
|
85
|
+
process_contents: str
|
|
86
|
+
min_occurs: int
|
|
87
|
+
max_occurs: int | None
|
|
88
|
+
order: int | None
|
|
89
|
+
|
|
90
|
+
|
|
82
91
|
@dataclass(frozen=True)
|
|
83
92
|
class ChoiceRequirement:
|
|
84
93
|
names: tuple[str, ...]
|
|
@@ -307,12 +316,13 @@ def multiplied_max(left: int | None, right: int | None) -> int | None:
|
|
|
307
316
|
|
|
308
317
|
def child_rules_for_complex_type(
|
|
309
318
|
complex_type: ET.Element,
|
|
310
|
-
) -> tuple[list[ChildRule], list[ChoiceRequirement]]:
|
|
319
|
+
) -> tuple[list[ChildRule], list[WildcardRule], list[ChoiceRequirement]]:
|
|
311
320
|
particle = particle_for_complex_type(complex_type)
|
|
312
321
|
if particle is None:
|
|
313
|
-
return [], []
|
|
322
|
+
return [], [], []
|
|
314
323
|
|
|
315
324
|
rules: list[ChildRule] = []
|
|
325
|
+
wildcard_rules: list[WildcardRule] = []
|
|
316
326
|
requirements: list[ChoiceRequirement] = []
|
|
317
327
|
next_order = 0
|
|
318
328
|
|
|
@@ -337,6 +347,25 @@ def child_rules_for_complex_type(
|
|
|
337
347
|
)
|
|
338
348
|
)
|
|
339
349
|
|
|
350
|
+
def add_wildcard(
|
|
351
|
+
wildcard: ET.Element,
|
|
352
|
+
*,
|
|
353
|
+
order: int | None,
|
|
354
|
+
optional_by_choice: bool,
|
|
355
|
+
max_multiplier: int | None,
|
|
356
|
+
) -> None:
|
|
357
|
+
minimum = occurs_value(wildcard.attrib.get("minOccurs"), 1) or 0
|
|
358
|
+
maximum = occurs_value(wildcard.attrib.get("maxOccurs"), 1)
|
|
359
|
+
wildcard_rules.append(
|
|
360
|
+
WildcardRule(
|
|
361
|
+
namespace=wildcard.attrib.get("namespace", "##any"),
|
|
362
|
+
process_contents=wildcard.attrib.get("processContents", "strict"),
|
|
363
|
+
min_occurs=0 if optional_by_choice else minimum,
|
|
364
|
+
max_occurs=multiplied_max(maximum, max_multiplier),
|
|
365
|
+
order=order,
|
|
366
|
+
)
|
|
367
|
+
)
|
|
368
|
+
|
|
340
369
|
def walk_group(
|
|
341
370
|
group: ET.Element,
|
|
342
371
|
*,
|
|
@@ -369,6 +398,13 @@ def child_rules_for_complex_type(
|
|
|
369
398
|
optional_by_choice=True,
|
|
370
399
|
max_multiplier=effective_max,
|
|
371
400
|
)
|
|
401
|
+
elif child_kind == "any":
|
|
402
|
+
add_wildcard(
|
|
403
|
+
child,
|
|
404
|
+
order=choice_order,
|
|
405
|
+
optional_by_choice=True,
|
|
406
|
+
max_multiplier=effective_max,
|
|
407
|
+
)
|
|
372
408
|
elif child_kind in {"sequence", "all", "choice"}:
|
|
373
409
|
walk_group(
|
|
374
410
|
child,
|
|
@@ -395,6 +431,17 @@ def child_rules_for_complex_type(
|
|
|
395
431
|
optional_by_choice=optional_by_choice or group_min == 0,
|
|
396
432
|
max_multiplier=effective_max,
|
|
397
433
|
)
|
|
434
|
+
elif child_kind == "any":
|
|
435
|
+
child_order = fixed_order
|
|
436
|
+
if child_order is None and ordered and group_ordered:
|
|
437
|
+
child_order = next_order
|
|
438
|
+
next_order += 1
|
|
439
|
+
add_wildcard(
|
|
440
|
+
child,
|
|
441
|
+
order=child_order,
|
|
442
|
+
optional_by_choice=optional_by_choice or group_min == 0,
|
|
443
|
+
max_multiplier=effective_max,
|
|
444
|
+
)
|
|
398
445
|
elif child_kind in {"sequence", "all", "choice"}:
|
|
399
446
|
walk_group(
|
|
400
447
|
child,
|
|
@@ -405,7 +452,7 @@ def child_rules_for_complex_type(
|
|
|
405
452
|
)
|
|
406
453
|
|
|
407
454
|
walk_group(particle, ordered=local_name(particle.tag) == "sequence")
|
|
408
|
-
return rules, requirements
|
|
455
|
+
return rules, wildcard_rules, requirements
|
|
409
456
|
|
|
410
457
|
|
|
411
458
|
def issue(
|
|
@@ -688,6 +735,31 @@ def element_namespace(tag: str) -> str | None:
|
|
|
688
735
|
return tag[1:].split("}", 1)[0]
|
|
689
736
|
|
|
690
737
|
|
|
738
|
+
def wildcard_matches_namespace(namespace_rule: str, namespace: str | None) -> bool:
|
|
739
|
+
tokens = namespace_rule.split()
|
|
740
|
+
if "##any" in tokens:
|
|
741
|
+
return True
|
|
742
|
+
if "##local" in tokens and namespace is None:
|
|
743
|
+
return True
|
|
744
|
+
if "##targetNamespace" in tokens and namespace == SML_NAMESPACE:
|
|
745
|
+
return True
|
|
746
|
+
if "##other" in tokens and namespace not in {None, SML_NAMESPACE}:
|
|
747
|
+
return True
|
|
748
|
+
return namespace in tokens
|
|
749
|
+
|
|
750
|
+
|
|
751
|
+
def wildcard_namespace_description(namespace_rule: str) -> str:
|
|
752
|
+
if namespace_rule == "##any":
|
|
753
|
+
return "any namespace"
|
|
754
|
+
if namespace_rule == "##local":
|
|
755
|
+
return "the local namespace"
|
|
756
|
+
if namespace_rule == "##targetNamespace":
|
|
757
|
+
return f"the target namespace {SML_NAMESPACE}"
|
|
758
|
+
if namespace_rule == "##other":
|
|
759
|
+
return "a namespace other than the SXSD target namespace"
|
|
760
|
+
return f"namespace {namespace_rule}"
|
|
761
|
+
|
|
762
|
+
|
|
691
763
|
def validate_element_children(
|
|
692
764
|
element: ET.Element,
|
|
693
765
|
path: str,
|
|
@@ -696,8 +768,10 @@ def validate_element_children(
|
|
|
696
768
|
) -> tuple[list[dict[str, Any]], dict[int, ElementRule]]:
|
|
697
769
|
tag = local_name(element.tag)
|
|
698
770
|
complex_type = complex_type_for_element(element_rule, model)
|
|
699
|
-
child_rules, choice_requirements = (
|
|
700
|
-
child_rules_for_complex_type(complex_type)
|
|
771
|
+
child_rules, wildcard_rules, choice_requirements = (
|
|
772
|
+
child_rules_for_complex_type(complex_type)
|
|
773
|
+
if complex_type is not None
|
|
774
|
+
else ([], [], [])
|
|
701
775
|
)
|
|
702
776
|
rules_by_name: dict[str, list[ChildRule]] = {}
|
|
703
777
|
for child_rule in child_rules:
|
|
@@ -706,19 +780,37 @@ def validate_element_children(
|
|
|
706
780
|
issues: list[dict[str, Any]] = []
|
|
707
781
|
matched: dict[int, ElementRule] = {}
|
|
708
782
|
counts: dict[str, int] = {}
|
|
783
|
+
wildcard_counts: dict[int, int] = {}
|
|
709
784
|
latest_order = -1
|
|
710
785
|
for child in element:
|
|
711
786
|
child_name = local_name(child.tag)
|
|
712
787
|
child_path = f"{path}/{child_name}"
|
|
713
788
|
candidates = rules_by_name.get(child_name, [])
|
|
714
|
-
|
|
789
|
+
wildcard_match = next(
|
|
790
|
+
(
|
|
791
|
+
(index, wildcard_rule)
|
|
792
|
+
for index, wildcard_rule in enumerate(wildcard_rules)
|
|
793
|
+
if wildcard_matches_namespace(
|
|
794
|
+
wildcard_rule.namespace,
|
|
795
|
+
element_namespace(child.tag),
|
|
796
|
+
)
|
|
797
|
+
),
|
|
798
|
+
None,
|
|
799
|
+
)
|
|
800
|
+
if not candidates and wildcard_match is None:
|
|
801
|
+
expected_children = sorted(rules_by_name)
|
|
802
|
+
expected_children.extend(
|
|
803
|
+
wildcard_namespace_description(rule.namespace) for rule in wildcard_rules
|
|
804
|
+
)
|
|
715
805
|
issues.append(
|
|
716
806
|
issue(
|
|
717
807
|
"sxsd_unexpected_child",
|
|
718
808
|
child_path,
|
|
719
809
|
child_name,
|
|
720
810
|
attr=None,
|
|
721
|
-
expected="one of: " + ", ".join(
|
|
811
|
+
expected="one of: " + ", ".join(expected_children)
|
|
812
|
+
if expected_children
|
|
813
|
+
else "no child elements",
|
|
722
814
|
actual=child_name,
|
|
723
815
|
message=f"unexpected SXSD child <{child_name}> under <{tag}> at {child_path}",
|
|
724
816
|
hint=f"Move or remove <{child_name}> so <{tag}> follows the SXSD child structure.",
|
|
@@ -726,6 +818,40 @@ def validate_element_children(
|
|
|
726
818
|
)
|
|
727
819
|
continue
|
|
728
820
|
|
|
821
|
+
if not candidates and wildcard_match is not None:
|
|
822
|
+
wildcard_index, wildcard_rule = wildcard_match
|
|
823
|
+
if wildcard_rule.order is not None:
|
|
824
|
+
if wildcard_rule.order < latest_order:
|
|
825
|
+
issues.append(
|
|
826
|
+
issue(
|
|
827
|
+
"sxsd_invalid_child_order",
|
|
828
|
+
child_path,
|
|
829
|
+
child_name,
|
|
830
|
+
attr=None,
|
|
831
|
+
expected="children in xs:sequence order",
|
|
832
|
+
actual=child_name,
|
|
833
|
+
message=f"SXSD child <{child_name}> is out of order under <{tag}> at {child_path}",
|
|
834
|
+
hint=f"Reorder <{child_name}> according to the SXSD sequence for <{tag}>.",
|
|
835
|
+
)
|
|
836
|
+
)
|
|
837
|
+
latest_order = max(latest_order, wildcard_rule.order)
|
|
838
|
+
wildcard_counts[wildcard_index] = wildcard_counts.get(wildcard_index, 0) + 1
|
|
839
|
+
actual_count = wildcard_counts[wildcard_index]
|
|
840
|
+
if wildcard_rule.max_occurs is not None and actual_count > wildcard_rule.max_occurs:
|
|
841
|
+
issues.append(
|
|
842
|
+
issue(
|
|
843
|
+
"sxsd_too_many_children",
|
|
844
|
+
child_path,
|
|
845
|
+
child_name,
|
|
846
|
+
attr=None,
|
|
847
|
+
expected=f"at most {wildcard_rule.max_occurs} child from {wildcard_namespace_description(wildcard_rule.namespace)}",
|
|
848
|
+
actual=actual_count,
|
|
849
|
+
message=f"too many wildcard SXSD children under <{tag}> at {path}",
|
|
850
|
+
hint=f"Keep at most {wildcard_rule.max_occurs} child from {wildcard_namespace_description(wildcard_rule.namespace)} under <{tag}>.",
|
|
851
|
+
)
|
|
852
|
+
)
|
|
853
|
+
continue
|
|
854
|
+
|
|
729
855
|
child_rule = candidates[0]
|
|
730
856
|
if child_rule.order is not None:
|
|
731
857
|
if child_rule.order < latest_order:
|
|
@@ -777,6 +903,24 @@ def validate_element_children(
|
|
|
777
903
|
)
|
|
778
904
|
)
|
|
779
905
|
|
|
906
|
+
for wildcard_index, wildcard_rule in enumerate(wildcard_rules):
|
|
907
|
+
actual_count = wildcard_counts.get(wildcard_index, 0)
|
|
908
|
+
if wildcard_rule.min_occurs <= actual_count:
|
|
909
|
+
continue
|
|
910
|
+
namespace_description = wildcard_namespace_description(wildcard_rule.namespace)
|
|
911
|
+
issues.append(
|
|
912
|
+
issue(
|
|
913
|
+
"sxsd_missing_required_child",
|
|
914
|
+
path,
|
|
915
|
+
tag,
|
|
916
|
+
attr=None,
|
|
917
|
+
expected=f"at least {wildcard_rule.min_occurs} child from {namespace_description}",
|
|
918
|
+
actual=actual_count,
|
|
919
|
+
message=f"missing required wildcard SXSD child under <{tag}> at {path}",
|
|
920
|
+
hint=f"Add at least {wildcard_rule.min_occurs} child from {namespace_description} under <{tag}>.",
|
|
921
|
+
)
|
|
922
|
+
)
|
|
923
|
+
|
|
780
924
|
for requirement in choice_requirements:
|
|
781
925
|
actual_count = sum(counts.get(name, 0) for name in requirement.names)
|
|
782
926
|
expected_names = ", ".join(requirement.names)
|