This commit is contained in:
2026-08-11 16:23:58 +02:00
parent 21c2275c00
commit b5e055216c
10 changed files with 292 additions and 27 deletions
+52
View File
@@ -1906,3 +1906,55 @@ W3DContainer:AUMCV_HOVER
`docs/plan.md` 的 manifest 建模小节补充:`assetsById` 必须保留同 id 的不同
类型定义,去重身份为 `(type, file, line)`。
---
## 二十八、问题分析(2026-08-11):xi:include 无 xpointer 语义与片段文件诊断(P0)
### 现象
`Data/Includes/GenericCelestialBuildingSuicide.xml` 这类被 `xi:include` 引用的
片段文件在独立打开时被报一串错误:`DieMuxData` 报 `missing-id`(“顶层资产需要
id”),wrapper 根不在 XSD 里的文件报 `unknown-element`,引用在完整索引下能解析
前还会报未解析引用。
### 根因
1. **无 `xpointer` 的展开语义错误**`expandDocument` 把目标 `root.children`
拼进父节点。按 XInclude 语义(也是 Corona 的实际用法),没有 `xpointer` 时应
整体包含目标文档的根元素。`GenericCelestialBuildingSuicide.xml` 的根
`CreateObjectDie` 本身就是要放进 GameObject 的模块;旧实现会丢掉它,只把
`DieMuxData` 拼进去。
2. **诊断层把片段当完整文档**:`isTopLevel` 假定根一定是 `AssetDeclaration`
于是片段根的子元素被当成顶层资产要求 id;未知 wrapper 根也被当成未知元素。
3. **引用/define 与上下文耦合**:片段里的引用可能由 include 者(或 include 者
的 include 链)提供,独立打开片段时无法可靠判定。
### 修复(P0,不猜测外部上下文)
1. `logicalTree.expandDocument`:无 `xpointer` 时 `handleChild(parse.root)`
整体包含目标根元素;有 `xpointer` 时保持 `/n:Name/child::*` 语义。
2. `diagnostics` 片段模式:根 localName 不是 `AssetDeclaration` 即为片段。
- 一律跳过顶层 `missing-id` / 跨文件重复 id、未解析引用、未定义 `$DEFINE`
- 根是已知 XSD 元素时(如 `CreateObjectDie`),根自身提供类型上下文,整棵子树
的未知元素 / 未知属性仍正常校验;
- 根不在 XSD 中(wrapper/container,如 `CommonArmorDraws`)时,只报 XML 语法
与片段内部 `xi:include` / `<Include>` 目标缺失,其余检查延后到上下文诊断。
3. 新增 `checkXiInclude``xi:include` 目标缺失在 Problems 中上报
`include-not-found`(此前只在 indexer 内部诊断)。
### 测试(202 → 202 全绿)
- `localScope.test.mjs`:无 `xpointer` 的 `xi:include` 把目标根元素
`CreateObjectDie` 整体拼入 `Behaviors``DieMuxData` 仍挂在它下面;
- `contentFeatures.test.mjs`:片段已知根不再报 `missing-id` / 未解析引用,但子树
未知属性仍报;未知 wrapper 根不报元素/属性,片段内部缺失 `xi:include` 仍报;
完整 `AssetDeclaration` 文档的顶层 id 检查不受影响。
### 边界与后续
- **P1 上下文诊断**indexer 增加“反向 include 表”(`xi:include` 目标 →
include 者列表),打开片段时用 include 者的逻辑树做真实上下文校验,再恢复引用 /
define / 子元素结构检查。多上下文取并集去重。
- `<Include type="all|instance|reference">` 与 `xi:include` 语义不同:前者的目标
是完整 `AssetDeclaration`,不进入片段模式;后者才允许片段文件。
+9 -6
View File
@@ -464,7 +464,7 @@ test/
展开(第十二轮,见第六节);顶层 `<Include type="all">``inheritFrom` +
`xai:joinAction` 的深合并仍未实现,后续如需要“当前文档视角的全量合并诊断”再继续。
## 六、include 展开设计备忘(2026-08-01xi:include 部分已实施于第十二轮)
## 六、include 展开设计备忘(2026-08-01xi:include 部分已实施于第十二轮,无 xpointer 语义与片段诊断见第二十八轮
> 目的:集中记录 include 处理相关的现状、结论与设计,下次遇到 include 问题时从这里继续,
> 并在实施后把结果回写本节。
@@ -477,7 +477,8 @@ test/
| `reference` → builtmods manifest 解析 / 缺失回退占位 XML | 已实现 |
| 嵌套 `xi:include`(任意层级):目标可索引、缺失报 `include-not-found`、Ctrl+点击跳转、`href` hover 解析目标 | 已实现(第二轮 + 第五轮) |
| `xi:include` 及其属性不参与 XSD 校验(外来命名空间守卫 `isXsdElementName` / `isXsdAttributeName` | 已实现(第五轮) |
| include 目标内容“虚拟合并”进父文档的逻辑树 | 已实现 `xi:include`(第十二轮);顶层 `<Include type="all">` 仍不展开 |
| include 目标内容“虚拟合并”进父文档的逻辑树 | 已实现 `xi:include`(第十二轮);**无 `xpointer` 时整体包含目标根元素**(第二十八轮修正);顶层 `<Include type="all">` 仍不展开 |
| 片段文件(根非 `AssetDeclaration`)的诊断 | 已实现 P0(第二十八轮):跳过顶层 id/重复/引用/define 检查;根为已知 XSD 元素时仍校验子树;根未知时只报语法与 include 缺失 |
### 2. 已确认的方向
@@ -488,9 +489,11 @@ BAB`defaultscript.cs`)编译时正是这样把整个 Mod 合并成一份大
- **不要**把 include 目标展开成文本再整体重新解析:源码偏移会断裂,诊断 / 跳转 / hover /
补全全部无法映射回原始文件。
- **要做**的是:解析器逐文件解析(现状不变);展开器把目标文件选中节点`xpointer`
子集挂进父元素,节点保留各自的源文件与原始偏移(来源追溯)。后续分析跑在逻辑树上,
范围映射按节点 `sourceFile` 回到对应文件的 lineMap。
- **要做**的是:解析器逐文件解析(现状不变);展开器把目标文件选中节点挂进父元素——
`xpointer` 时取 `/n:Name/child::*` 选中 children,无 `xpointer` 时按 XInclude 语义
整体包含目标根元素(RA3 片段如 `CreateObjectDie` 依赖这一行为);节点保留各自的源文件
与原始偏移(来源追溯)。后续分析跑在逻辑树上,范围映射按节点 `sourceFile` 回到对应
文件的 lineMap。
- 现有 `parseXml` 已记录标签 / 属性 / 值的起止偏移,`XmlElement` 结构可直接复用;拼接时
用浅拷贝节点壳并重建 parent 链,避免破坏目标文件缓存树自身的 parent 指针。
@@ -498,7 +501,7 @@ BAB`defaultscript.cs`)编译时正是这样把整个 Mod 合并成一份大
| 构造 | 拼入逻辑树 | 理由 |
|---|---|---|
| `xi:include` | ✅ | 内容并入父元素(HeadlightDraw2 场景) |
| `xi:include` | ✅ | `xpointer`:选中容器 children;无 `xpointer`:整体包含目标根元素(CreateObjectDie / TechUpgradeReceiver 等片段场景) |
| EA `<Include type="all">` | ✅ | BAB“内容合并”,等价于复制进来 |
| `type="instance"` | ❌ | 只影响编译可见性;拼树会把 BaseVehicle 的顶层资产错误塞进当前文档 |
| `type="reference"` | ❌ | manifest 编译产物,无文本内容 |