目錄 / Table of Contents

API 表面一致性

本文件定義 OdfKit 公開 API 的長期命名與分層規則。它是實作與審查 時判斷「是否需要一級 C# 物件模型」的依據,並同步排除專案既有文件已確認 不是核心目標的項目。

目前靜態盤點結果見 docs/api-surface-inventory.md

1. API 分層

層級 名稱 完成線 主要入口
L0 封裝 API 所有 ODF package entry、manifest、media、RDF 與 unknown entry 可存取、儲存與來回讀寫。 OdfPackageOdfDocument
L1 型別化 DOM API 所有 ODF 1.4 schema element / attribute 可透過產生的 wrapper、型別化屬性 helper 或 schema-aware DOM 存取。 OdfNodeOdfElement、generated DOM wrappers、OdfTypedDomCoverage
L2 語意外觀層 API 常見文件工作流程具備高階 C# 外觀層,不需要呼叫端理解 XML 細節。 TextDocumentSpreadsheetDocumentPresentationDocumentDrawingDocument、Chart / Formula / Image / Database facade
L3 外部引擎邊界 需要辦公軟體行為、外部環境或不可穩定受控化的能力,只能作為 extension 或 optional validation。 OdfKit.Extensions.Rendering、LibreOffice / Office interop scripts

「所有 ODF 功能可用 C# 存取」表示 L0 + L1 必須完整;「所有常見工作流程有 一級 C# 物件模型」表示 L2 必須覆蓋高價值使用情境。L3 不屬於核心 API 完成條件。

L2 外觀層設計基準

  • 高階物件必須直接組合既有 OdfNode/typed DOM 與 package resource,不維護另一份平行狀態。 ODF Toolkit 的舊 Simple API 因大量重複 ODFDOM 程式碼及脫節的清單模型而被棄用;OdfKit 不採用相同 fork 式架構。
  • 集合公開為唯讀快照或受控 editor;新增、更新、移除與清除使用具名方法,不讓呼叫端直接 修改 backing list。Apache POI 的 XDDFChartData 同樣要求使用 addSeriesremoveSeries(index),並明確警告直接修改回傳 List 可能破壞文件;LibreOffice Chart2 XDataSeriesContainer 亦分別定義 add/get/set/remove。
  • 外觀層完成度以工作流程與逐操作證據衡量,不以公開型別或方法總數衡量。若 ODF 規格本身 限制結構(例如嚴格 ODI 僅有一個 draw:frame 且其中僅有一個 draw:image),不得為增加 API 數量而虛構圖層、群組或其他 schema 不存在的模型。

參考:ODF Toolkit Simple API deprecationApache POI XDDFChartDataLibreOffice XDataSeriesContainerOASIS ODF 1.4 Part 3

次要格式深度工作流

ODC、ODB、ODF 與 ODI 的高階 API 以「能完成安全工作流」而非方法數量判定深度:

格式 已完成的受控工作流 邊界
ODC 序列新增、editor 更新、移除、清除、重排,以及 immutable snapshot 的單筆/批次套用;操作既有節點並保留 style、已知子項與未知內容。 不暴露可直接修改的 backing list。
ODB table/query/form/report/data-source setting 的查找、新增、desired-state 更新、移除與清除;schema 欄位、主鍵、外鍵與索引只透過受控 editor 修改。 只管理 ODF 資料庫描述,不連線或執行 SQL。
ODF 真正唯讀的 immutable token tree、predicate/factory 單一/全樹替換、屬性移除/清除、文件層移除與清除。 全樹替換不再次處理 replacement subtree;移除必要複合子節點時以空 mrow 維持結構。
ODI FindImageFrame nullable lookup、bytes 單筆/批次替換、layout/metadata、rotation、crop、filter、批次更新與檢查報告。 strict ODF 1.4 只有單一 draw:framedraw:image,不建立虛構的多圖文件模型。

集合重排、desired-state 更新與 immutable tree rewrite 都必須保留無關及 foreign namespace 內容;公開 API 基線與 round-trip 測試是此工作流契約的一部分。

上述四項是高階 API 結構性加厚的完成線。完成線之後,不再以公開方法數量、 競品型別數量或 schema 元素數量驅動 facade 擴張;新高階 API 必須由可重現的真實使用案例、 ODF 規格更新或已確認缺陷觸發,並在同一變更中補齊工作流證據。Options、結果 DTO、 公式 AST 與 evaluation context 的可修改集合不屬於文件 DOM backing collection, 不得被機械改寫成 editor。

2. 命名契約

新增或破壞性重新命名公開 API 時,請使用以下規則;本專案尚未正式發佈 套件,因此允許一次性重構儲存庫內所有使用點,不保留舊名稱 shim。

形狀 用途 回傳語意
Create / Load / Save / Validate 文件生命週期。 依既有文件 API 慣例。
Builder() Fluent 建立入口。 回傳 builder;builder 使用 With* 設定狀態、Add* 新增內容。
Add* 新增節點、實體或 relation。 回傳新增項目或 void,不得表示查找。
Get* 讀取快照、摘要、集合或不可變資訊。 集合讀取統一使用 Get* 或屬性。
Set* 設定或覆寫單一狀態。 回傳更新後外觀層或 void
Update* 依回呼、request 或批次規則修改既有內容。 回傳變更數量或更新結果。
Remove* 移除指定內容。 不存在時優先回傳 false;輸入無效才拋例外。
Find* 查找單一可選項。 找不到回傳 null。不得用於集合。
Try* 嘗試取得或執行可能失敗的操作。 回傳 bool,搭配 out 或明確結果。

List* 不作為新的公開 API 命名。若需要列出集合,使用 Get* 或唯讀集合屬性。

低階 DOM / 型別化屬性 accessor 可保留 Get*,即使回傳 nullable;這些 API 描述的是「讀取目前節點或屬性的值」,不是依領域 key 查找語意物件。 例如 OdfNode.GetAttributeOdfElement.Get*AttributeValue 與產生的 wrapper 屬性 setter 內部使用的 remove helper,不適用 L2 外觀層的 Find* 規則。

Clear* 表示清空一段可重建狀態或重設目前設定,可維持 no-op 命令語意與 void 回傳;若 API 需要表達「移除某個指定項目是否成功」,應提供或改用 Remove*,並遵守 bool 成功/失敗語意。

Database 與 Image 目前不強制補 Builder() 入口。Database 的主要 L2 工作流程 是 table / query / form / report CRUD 與 schema 設定;Image 的主要 L2 工作流程 是載入、框架、濾鏡與圖片 bytes 變更。這兩者沒有足以降低複雜度的常見 fluent 建立流程時,可保留 Create / Load / Set* / Add* / Find* 組合。

已套用的破壞性重新命名

第一批已將集合型 Find* 改為 Get*,以符合「Find* 只回傳單一可選項」:

範圍 新名稱 理由
Schema name-class collection query GetMatchingNameClasses 回傳多個 name class。
RDF triple collection query GetTriples 回傳多個 RDF triple。
Math token collection query GetAll 回傳多個 Math token。
Workbook formula-cell predicate query GetFormulaCells overload 回傳多個公式儲存格。
Worksheet formula-cell predicate query GetFormulaCells overload 回傳多個公式儲存格。
Tracked-change affected-node query GetAffectedNodesForFormatChange 回傳多個 DOM 節點。

第二批已將語意明確的單一 nullable lookup 從 Get* 改為 Find*

範圍 新名稱 理由
Workbook sheet lookup by name FindSheet 依名稱查找單一工作表,找不到回傳 null
Formula annotation lookup by encoding FindAnnotation 依 encoding 查找單一 MathML annotation,找不到回傳 null
Spreadsheet cell annotation lookup FindAnnotation 查找單一儲存格批注,找不到回傳 null

第三批已統一指定項目移除 API 的成功/失敗語意:

範圍 回傳語意
Package entry removal 移除 entry、manifest 項目或 entry order 項目時回傳 true
DOM attribute / child removal 目標存在且已移除時回傳 true;目標不屬於目前節點或不存在時回傳 false
Spreadsheet hyperlink / annotation removal 移除既有內容時回傳 true;沒有可移除內容時回傳 false
Spreadsheet row / column page break removal 目標分頁符存在且已移除時回傳 true;不存在時不建立新節點並回傳 false
Presentation placeholder removal 至少移除一個指定型態的 placeholder 時回傳 true

第四批已將依 key、name 或 dimension 查找單一 nullable 項目的 Get* 改為 Find*

範圍 新名稱
Database query optional children FindQueryOrderStatementFindQueryFilterStatementFindQueryUpdateTable
Chart series optional children FindDataLabelsFindErrorIndicatorFindRegressionCurveFindMeanValue
Chart document optional lookups FindSeriesDataLabelsFindAxisInfoFindAxisTitle
Presentation page layout lookup FindPresentationPageLayout
Image frame filter lookup FindImageFilter
Package entry encryption lookup FindEntryEncryptionInfo
Custom metadata property lookup FindCustomProperty

3. 明確排除的目標

下列項目已由專案文件確認不屬於核心 API 目標,不應因 API 一致性工作而被 重新納入:

  • 完整物理分頁排版器、像素級高保真渲染與所有 LibreOffice 版本的像素一致性。
  • 試算表完整公式重算、volatile function、多使用者計算狀態與任意外部連結資料來源。 Pivot 已提供有界重算、分組、總計與 Show Values As;完整 office suite 的互動式 pivot cache、slicer 與視覺化編輯器仍不在核心範圍。
  • SmartArt 智慧圖形、複雜形狀布局器與 Office 專屬 layout 相容層。
  • 完整多人協同演算法、任意衝突合併、undo stack、OT、CRDT、完整 drawing DOM、動態表格擴張與 header/footer/note selection 完整語意。
  • 通用 RELAX NG validator;核心 validator 只服務內建 ODF profile gate。
  • 外部 Office / LibreOffice / PDF pixel diff / large corpus 驗收進入主 CI Smoke。
  • 不可再散布 corpus、商業 SDK 輸出或外部專案原始碼作為 golden。

相關邊界來源:docs/udx-non-goals.mddocs/rendering-backend-deployment.mddocs/libreoffice-interop-matrix.mddocs/ci-cd.mddocs/provenance/clean-room-source-index.md

4. 文件與相容性要求

  • 每次 breaking rename 必須同步更新 repo 內所有使用點,包含 tests、samples、docs、 tools、CLI 與 extensions。
  • 若舊名稱存在於 corpus fixture、JSON wire shape 或外部格式資料中,不改資料格式; 只改 C# API。
  • 手寫 public / protected API 必須具備雙語 XML 文件。generated DOM wrapper 可由 generator 層統一豁免或改善,不進行逐檔手改。
  • 新 API 不得以 #pragma warning disable 1591 規避文件要求。