# 受控包编辑基础

`fsys.openXml.editor.open(path,options)` 返回只读源包上的编辑会话，组合已有读取器与 writer。无需 Office；支持替换**现有部件**；0.11.0 增加原子新增/删除 `applyParts`，自动维护内容类型。它不是完整 OPC 编辑器，关系与文种语义仍由高层负责。

- `readPart/readXml` 优先读已修改字节；DOM 是独立对象，必须显式 setXml 才提交内存修改。
- `setPart(name,data)` 替换现有部件；buffer 复制当前字节；setParts 数组先完整校验后提交。
- `applyParts([{name,data,contentType},{name,remove=true}])` 原子新增/替换/删除。新增必须给内容类型，现有类型不能隐式改变；不能直接传 `[Content_Types].xml`，不能删除主部件/包根关系。添加类型覆盖、删除对应覆盖由本方法完成，失败不提交部分修改。不会自动修复关系；只有清楚包结构的调用者才应直接使用。
- `setXml(name,node)` 使用 xml.serialize 统一 UTF-8 声明并复验良构；不做 XSD 校验。
- `listParts/getMainPart/getContentType/getRelationships/changedParts/close` 提供现有包信息及生命周期。
- save 默认不覆盖且禁止覆盖源件；未修改部件逐件 CRC 核对后重压缩，解压内容保持原字节；不保留 ZIP 元数据/目录项或容器二进制布局。
- 拒绝 `_xmlsignatures/` 包数字签名。不会执行宏/嵌入对象，不跟随外部关系。

```aardio
import fsys.openXml.editor;
var doc,err=fsys.openXml.editor.open("/input.pptx");
if(!doc) return null,err;
var parts=doc.listParts();
var changes=doc.changedParts();
doc.close();
return {parts=parts;changes=changes};
```

部件是包内 URI，不是文件系统路径。直接 setPart 修改 XML 编码声明、关系、内容类型由调用者承担；applyParts 仅自动维护与本次条目变更对应的内容类型；高层受控 PPTX 操作优先使用 [pptx.editor](../pptx/editor/index.html)。
