# OfficeCLI Three-Layer Architecture L1 L2 L3 Explained: L1 Read, L2 DOM, and L3 Raw XML

> Understand OfficeCLI's three-layer architecture L1 L2 L3: L1 Read, L2 DOM, and L3 Raw XML. Explore progressive abstraction for Office document manipulation with iOfficeAI.

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

---

**OfficeCLI uses a three-layer architecture (L1 Read, L2 DOM, L3 Raw XML) that provides progressive abstraction levels for manipulating Office documents, from semantic views down to direct XPath access.**

The **iOfficeAI/OfficeCLI** repository implements a clean, three-layer architecture that separates concerns and gives developers flexible entry points for automating Word, Excel, and PowerPoint files. This **OfficeCLI three-layer architecture L1 L2 L3 explained** approach progressively exposes document internals, allowing users to start with high-level semantic operations and drop down to raw XML manipulation only when necessary.

## Understanding the Three-Layer Architecture

OfficeCLI organizes its functionality into three distinct abstraction layers, each designed for specific use cases and levels of control.

### L1 Read Layer – Semantic Views

The **L1 Read** layer provides *semantic* views of documents and operates as a read-only interface. It parses Office files into high-level models that are easy for humans and AI agents to understand and process.

**Typical L1 commands** include `view` operations that render documents as plain text, outlines, annotated HTML, or statistical summaries. For example, according to the source in [`README.md`](https://github.com/iOfficeAI/OfficeCLI/blob/main/README.md) at line 342, the command `officecli view report.docx annotated` generates human-readable document representations without exposing underlying XML complexity.

### L2 DOM Layer – Structured Element Model

The **L2 DOM** layer exposes a *structured* element model that can be queried and mutated using DOM-like operations. This layer abstracts raw XML details while enabling fine-grained element manipulation.

**Available L2 commands** include `get`, `query`, `set`, `add`, `remove`, `move`, and `swap` as documented in [`README.md`](https://github.com/iOfficeAI/OfficeCLI/blob/main/README.md) at line 345. These commands treat Office documents as navigable object trees where elements can be selected via paths and modified through property updates.

### L3 Raw XML Layer – Direct XPath Access

The **L3 Raw XML** layer gives direct *XPath* access to the underlying Office Open XML, acting as a universal fallback when higher-level operations cannot express specific modifications.

**L3 commands** include `raw`, `raw-set`, `add-part`, and `validate` as noted in [`README.md`](https://github.com/iOfficeAI/OfficeCLI/blob/main/README.md) at line 346. This layer is the most powerful—and risky—option, useful for edge cases requiring precise XML injection or manipulation that the DOM abstraction cannot handle.

## How the Layers Interact in Practice

The layers are **progressively more low-level**: you start with the simplest, most expressive API (L1) and only drop down to L2 or L3 when needed. This design keeps common operations simple while providing full control for advanced scenarios.

The implementation of watch-mode preview illustrates this layering explicitly. In [`src/officecli/Core/Watch/WatchServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/Watch/WatchServer.cs) at lines 81-86, Layer 1 handles Server-Sent Events (SSE) and DOM updates, while Layer 2 adds UI overlays including selection boxes, rubber-banding, and CSS injection. The coupling is explicit: Layer 1 calls `window._watchReapplyHook()` after each DOM mutation, and Layer 2 provides that hook to re-apply decorations.

Supporting this architecture:
- [`src/officecli/Resources/watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Resources/watch-sse-core.js) implements the SSE connection and DOM diff/patch logic (Layer 1)
- [`src/officecli/Resources/watch-overlay.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Resources/watch-overlay.js) adds UI decorations and selection marks (Layer 2)

## Code Examples by Layer

Each layer offers distinct syntax patterns appropriate to its abstraction level.

### L1 Read Examples

```bash

# Render presentation as high-fidelity HTML for visual inspection

officecli view deck.pptx html

# Generate text outline of document structure

officecli view report.docx outline

```

### L2 DOM Examples

```bash

# Update paragraph formatting using DOM path selection

officecli set report.docx /body/p[1] --prop bold=true

# Add shape to specific slide using element-level API

officecli add deck.pptx /slide[1] --type shape --prop text="Revenue ↑"

# Query elements matching specific criteria

officecli query report.docx /body/p --where "text contains 'Summary'"

```

### L3 Raw XML Examples

```bash

# Directly inject XML into first paragraph via XPath

officecli raw-set report.docx document \
  --xpath "//w:p[1]" \
  --action append \
  --xml '<w:r><w:t>Injected text</w:t></w:r>'

# Validate document XML structure

officecli validate report.docx

```

## Key Implementation Files

The three-layer architecture is documented and implemented across these critical source files:

- **[`README.md`](https://github.com/iOfficeAI/OfficeCLI/blob/main/README.md) (lines 342-347)** – Describes the three-layer model and maps commands to their respective layers
- **[`src/officecli/Core/Watch/WatchServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/Watch/WatchServer.cs) (lines 81-86)** – Demonstrates Layer 1 and Layer 2 coupling via the watch hook system
- **[`src/officecli/Resources/watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Resources/watch-sse-core.js)** – Implements Layer 1 SSE connection and DOM diff/patch logic
- **[`src/officecli/Resources/watch-overlay.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Resources/watch-overlay.js)** – Implements Layer 2 UI decorations and selection overlays

## Summary

- **L1 Read** provides semantic, read-only document views ideal for inspection and AI processing
- **L2 DOM** offers structured element manipulation via paths and properties without XML complexity
- **L3 Raw XML** enables direct XPath access for edge cases requiring precise XML control
- The architecture is progressive: start with L1, drop to L2 for mutations, and use L3 only when necessary
- Watch mode demonstrates practical layer interaction through the `window._watchReapplyHook()` coupling mechanism

## Frequently Asked Questions

### What is the difference between L2 DOM and L3 Raw XML in OfficeCLI?

**L2 DOM** operates on a structured element model using high-level paths like `/body/p[1]` and property settings, abstracting away XML namespaces and complex Office Open XML structures. **L3 Raw XML** requires explicit XPath expressions such as `//w:p[1]` and literal XML fragments, giving you direct access to the document's internal markup but requiring knowledge of Office XML schemas.

### When should I use L1 Read instead of L2 DOM?

Use **L1 Read** when you need to extract information, generate previews, or analyze document content without modifying the file. L1 is optimized for semantic understanding and read-only operations like generating HTML previews or text outlines. Switch to **L2 DOM** only when you need to modify document structure, formatting, or content programmatically.

### How does OfficeCLI handle layer coupling in watch mode?

According to the source in [`WatchServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WatchServer.cs), OfficeCLI decouples Layer 1 (core SSE and DOM updates) from Layer 2 (UI decorations) through a hook system. Layer 1 triggers `window._watchReapplyHook()` after each DOM mutation, while Layer 2 implements this hook to re-apply selection boxes and visual overlays, ensuring UI decorations persist across document updates without tightly coupling the rendering logic.

### Can I mix L2 and L3 commands in the same OfficeCLI workflow?

Yes, you can combine layers within the same workflow. Start with **L2 DOM** operations for standard modifications, then drop to **L3 Raw XML** only for specific edge cases where the DOM abstraction is insufficient. This hybrid approach leverages L2's safety and readability while reserving L3's power for complex XML manipulations that require precise control over namespaces or unsupported Office features.