# How Dump/Batch Round-Trip Serialization Works in OfficeCLI

> Understand OfficeCLI dump batch round-trip serialization. Learn how OfficeCLI replays commands to reconstruct or modify documents atomically using a record-and-replay workflow.

- Repository: [OfficeAI/OfficeCLI](https://github.com/iofficeai/OfficeCLI)
- Tags: internals
- Published: 2026-07-20

---

**OfficeCLI implements a reversible "record-and-replay" workflow where the `dump` command serializes a document subtree into a JSON array of `BatchItem` objects, and the `batch` command validates and replays those commands to reconstruct or modify the document atomically.**

The `iOfficeAI/OfficeCLI` repository provides a robust round-trip serialization mechanism that lets you export Office document structures as editable JSON scripts and later apply those scripts to recreate or modify documents. This dump/batch round-trip serialization powers document automation workflows by treating document mutations as version-controllable code.

## The Two Stages of Round-Trip Serialization

The serialization process splits into two complementary phases: **dump** for recording state and **batch** for replaying changes.

### Stage 1: Dump (Serialize)

When you execute a dump command, OfficeCLI opens the target file once via `DocumentHandlerFactory.Open` and delegates to a format-specific emitter. In [`src/officecli/CommandBuilder.Dump.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/CommandBuilder.Dump.cs) (lines **13‑33** define the CLI arguments, core logic starts at **39**), the appropriate emitter—`WordBatchEmitter`, `PptxBatchEmitter`, or `ExcelBatchEmitter`—walks the requested DOM path.

The emitter builds a `List<BatchItem>` describing each change needed to recreate the subtree. During traversal, any unsupported elements generate `CliWarning` objects (handled at lines **84‑95**). The system then serializes the list to compact JSON using `JsonSerializer.Serialize(items, BatchJsonContext.Default.ListBatchItem)` (lines **184‑186**). Depending on flags, the JSON writes to stdout, saves to a file (`--out`), or wraps in a standard envelope via `OutputFormatter.WrapEnvelope` (lines **191‑227**) that carries both data and warnings.

### Stage 2: Batch (Replay)

The batch command reverses the process. In [`src/officecli/CommandBuilder.Batch.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/CommandBuilder.Batch.cs) (argument definitions at lines **18‑33**, action body at **49‑65**), the command reads a JSON array from stdin, a file (`--input`), or an inline string (`--commands`).

If the JSON is an envelope produced by dump (`{ "success":…, "data": […] }`), the system automatically extracts the `data` array (lines **60‑67**). A pre-flight validation step (lines **92‑107**) ensures each object contains only `BatchItem.KnownFields` and rejects `null` entries.

The system opens the target document once via `DocumentHandlerFactory.Open`, then calls `ApplyBatchItems` (lines **50‑77**). This method iterates the list, invokes `ExecuteBatchItem` for each command, and records a `BatchResult`. For non-resident runs, OfficeCLI uses an atomic temporary copy strategy: it writes the document to a temp file, applies the batch, then swaps the temp over the original only if every item succeeds (lines **140‑170**). Finally, results format as a JSON envelope when `--json` is used (lines **216‑223**), with warnings emitted to stderr and embedded in the envelope.

## Emitter Architecture and DOM Traversal

The emitter layer abstracts document-specific logic into three specialized classes:

- **[`WordBatchEmitter.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordBatchEmitter.cs)**: Handles WordOpenXML structures and paragraph styles
- **[`PptxBatchEmitter.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/PptxBatchEmitter.cs)**: Processes slide shapes, text frames, and drawing elements
- **[`ExcelBatchEmitter.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ExcelBatchEmitter.cs)**: Manages worksheets, cells, and formulas

Each emitter implements the traversal logic called from [`CommandBuilder.Dump.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/CommandBuilder.Dump.cs) at lines **107‑119** (Word), **133‑140** (PowerPoint), and **156‑160** (Excel). These emitters translate proprietary Office formats into the neutral `BatchItem` representation, enabling cross-format scripting workflows.

## JSON Schema and Validation

The `BatchItem` class (defined in [`src/officecli/BatchItem.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/BatchItem.cs) and exposed via `BatchJsonContext`) establishes the contract between dump and batch operations. Each item contains fields such as `command`, `path`, and `props`.

During batch replay, the validation logic at lines **92‑107** of [`CommandBuilder.Batch.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/CommandBuilder.Batch.cs) enforces schema compliance by checking against `BatchItem.KnownFields`. This strict validation prevents corrupted or malformed JSON from partially modifying documents, ensuring that only well-formed commands reach the execution stage.

## Atomic Execution Guarantees

OfficeCLI guarantees document integrity through atomic batch application. When processing commands, the system creates a temporary copy of the target document (lines **140‑170** in [`CommandBuilder.Batch.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/CommandBuilder.Batch.cs)). All mutations occur on this temporary file. Only after `ApplyBatchItems` confirms that every `BatchItem` executed successfully does the system perform an atomic file swap, replacing the original with the modified temp file. This all-or-nothing approach ensures that documents remain unchanged if any command fails.

## Practical Round-Trip Examples

Export a PowerPoint slide subtree for editing:

```bash
officecli dump my.pptx /slide[2] --format batch -o slide2.json

```

Replay the exported batch to a new document:

```bash
officecli batch myCopy.pptx --input slide2.json

```

Perform a full round-trip with manual editing:

```bash

# Export entire document as batch script

officecli dump doc.docx / --format batch -o full.json

# Modify the JSON (e.g., change text content)

jq '.[] | select(.command=="add") | .props.text="Hello world!"' full.json > edited.json

# Apply edited batch to fresh copy

cp doc.docx docEdited.docx
officecli batch docEdited.docx --input edited.json

```

## Summary

- **Dump serialization** traverses documents via format-specific emitters, producing JSON arrays of `BatchItem` objects with optional warning envelopes.
- **Batch replay** validates input against `KnownFields`, executes commands via `ApplyBatchItems`, and guarantees atomic updates through temporary file swapping.
- **File locations**: Core logic resides in [`src/officecli/CommandBuilder.Dump.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/CommandBuilder.Dump.cs) and [`src/officecli/CommandBuilder.Batch.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/CommandBuilder.Batch.cs), with emitters in [`WordBatchEmitter.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordBatchEmitter.cs), [`PptxBatchEmitter.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/PptxBatchEmitter.cs), and [`ExcelBatchEmitter.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ExcelBatchEmitter.cs).
- **Integrity**: Atomic temp-file handling (lines **140‑170**) ensures documents update completely or not at all.

## Frequently Asked Questions

### What is the JSON schema for a BatchItem?

Each `BatchItem` follows a strict schema defined in [`src/officecli/BatchItem.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/BatchItem.cs) with fields restricted to `KnownFields`. Valid objects must include a `command` string and `path` specifier, may include a `props` object for parameters, and cannot contain `null` values at the root level. The `BatchJsonContext` provides source-generated serializers for high-performance JSON handling.

### How does OfficeCLI handle errors during batch replay?

According to [`src/officecli/CommandBuilder.Batch.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/CommandBuilder.Batch.cs) lines **140‑170**, OfficeCLI writes the document to a temporary file before applying any commands. If any `ExecuteBatchItem` call fails, the system discards the temporary file and leaves the original document untouched. Only successful completion of all items triggers the atomic swap to the target path.

### Can I edit the dumped JSON before replaying it?

Yes. The dump output is standard JSON that you can manipulate with tools like `jq` or any text editor. As long as the edited JSON maintains valid `BatchItem` structure and passes the `KnownFields` validation (lines **92‑107**), the batch command will replay your modifications. This enables templating workflows where you parameterize text, styles, or paths between extraction and application.

### Is the batch operation atomic across different Office formats?

Yes. Whether processing `.docx`, `.pptx`, or `.xlsx` files, OfficeCLI uses the same atomic temp-file pattern implemented in [`CommandBuilder.Batch.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/CommandBuilder.Batch.cs). The `DocumentHandlerFactory.Open` method provides a unified entry point for all formats, ensuring consistent single-file open semantics and atomic replacement guarantees across Word, PowerPoint, and Excel documents.