# How OfficeCLI's Three-Layer Architecture Works: L1 Read vs L2 DOM vs L3 Raw XML

> Understand OfficeCLI's three-layer architecture: L1 Read, L2 DOM, and L3 Raw XML. Learn how this structure separates high-level operations from low-level OpenXML editing.

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

---

**OfficeCLI abstracts Office document manipulation through a three-layer architecture—L1 Read (semantic), L2 DOM (structured query), and L3 Raw XML (direct access)—that separates high-level document operations from low-level OpenXML package editing.**

The iOfficeAI/OfficeCLI repository implements a clean abstraction strategy that protects developers from the complexity of OOXML while retaining full control when needed. This architecture, defined by the `IDocumentHandler` interface, provides three distinct access patterns that let you choose between convenience and precision.

## The Three-Layer Architecture Explained

OfficeCLI organizes document operations into a hierarchy of abstraction layers, with each layer exposing different capabilities and safety guarantees.

### Layer 1 (L1 Read): The Semantic Layer

The **semantic layer** provides human-readable, high-level views of documents without exposing underlying markup. According to the source code in [`src/officecli/Core/IDocumentHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/IDocumentHandler.cs), this layer implements methods like `ViewAsText`, `ViewAsAnnotated`, `ViewAsOutline`, and `ViewAsStats` [^58-L74^].

**Typical commands:**
- `officecli view text report.docx` – Extracts plain text content
- `officecli view annotated report.docx` – Shows text with semantic annotations
- `officecli view outline report.docx` – Displays document structure
- `officecli view stats report.docx` – Returns statistical summaries

This layer handles the semantic representation of the document, automatically translating requests into DOM operations while hiding XML complexity.

### Layer 2 (L2 DOM): The Query Layer

The **DOM layer** exposes a tree of `DocumentNode` objects that represent the document's logical structure. As defined in [`src/officecli/Core/IDocumentHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/IDocumentHandler.cs), this layer includes methods such as `Get`, `Query`, `Set`, `Add`, `Remove`, `Move`, and `CopyFrom` [^81-L98^].

**Capabilities:**
- Navigate logical element paths (e.g., `/paragraph[3]`, `/table[1]/row[2]`)
- Query nodes with selectors
- Manipulate properties using property maps

Concrete implementations in [`src/officecli/Handlers/WordHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/WordHandler.cs), [`ExcelHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ExcelHandler.cs), and [`PowerPointHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/PowerPointHandler.cs) provide format-specific DOM trees while maintaining a consistent interface across Word, Excel, and PowerPoint documents.

### Layer 3 (L3 Raw XML): The Raw Layer

The **raw layer** provides direct access to the underlying OpenXML parts. The `IDocumentHandler` interface declares `Raw` and `RawSet` methods (plus helper `AddPart`) for reading and writing exact XML content [^98-L106^].

**Use cases:**
- Insert custom XML fragments
- Edit parts not exposed by the DOM layer (e.g., `/styles`, [`/word/footnotes.xml`](https://github.com/iOfficeAI/OfficeCLI/blob/main//word/footnotes.xml))
- Execute XPath operations on specific document parts

Reference documentation in [`schemas/help/docx/raw.json`](https://github.com/iOfficeAI/OfficeCLI/blob/main/schemas/help/docx/raw.json) defines the command-line conventions for part paths and XPath selectors used by this layer.

## When to Use Each Access Level

Choose your access layer based on the operation's complexity and the level of control required.

**Use L1 Read when:**
- You need quick content extraction (text, statistics, outlines)
- You want safe, read-only access that cannot corrupt document structure
- You are building simple automation scripts that don't modify documents

**Use L2 DOM when:**
- You need to modify specific logical elements (paragraphs, tables, cells)
- You want structured access via paths like `/paragraph[2]`
- You are setting properties (e.g., `fontSize=12`, `style=Heading1`) on document elements
- You want validation and safety checks that prevent malformed XML

**Use L3 Raw XML only when:**
- The DOM layer cannot express the needed operation
- You must insert custom XML fragments or edit extension parts
- You are performing low-level package surgery (e.g., modifying [`document.xml`](https://github.com/iOfficeAI/OfficeCLI/blob/main/document.xml) directly)
- You accept the risk of corrupting the OOXML package structure

## Technical Implementation

The `IDocumentHandler` interface unifies these layers across all document types. Each Office format (Word, Excel, PowerPoint) implements this interface in its respective handler class:

- [`src/officecli/Handlers/WordHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/WordHandler.cs) – Word document implementation
- [`src/officecli/Handlers/ExcelHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/ExcelHandler.cs) – Excel workbook implementation  
- [`src/officecli/Handlers/PowerPointHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/PowerPointHandler.cs) – PowerPoint presentation implementation

The CLI commands are wired through [`src/officecli/CommandBuilder.Raw.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/CommandBuilder.Raw.cs), which handles argument parsing for the `raw` and `raw-set` operations that target L3 functionality.

## Practical Examples

**L1 Read (Semantic Layer):**

```bash
officecli view text report.docx

```

**L2 DOM (Query Layer) – Get a specific node:**

```bash
officecli get report.docx /paragraph[3]

```

**L2 DOM (Query Layer) – Set a property:**

```bash
officecli set report.docx /paragraph[3] style=Heading1

```

**L3 Raw XML (Raw Layer) – Read raw XML:**

```bash
officecli raw report.docx /document

```

**L3 Raw XML (Raw Layer) – Remove element via XPath:**

```bash
officecli raw-set report.docx /document \
  --xpath "//w:p[1]" \
  --action remove

```

## Summary

- **L1 Read** provides safe, high-level semantic access for text extraction and document analysis without XML exposure.
- **L2 DOM** offers structured manipulation through logical node paths and property maps, suitable for most document editing tasks.
- **L3 Raw XML** grants direct OpenXML package access for edge cases requiring custom markup or unsupported document parts.
- The `IDocumentHandler` interface enforces consistency across Word, Excel, and PowerPoint handlers while separating concerns between abstraction levels.

## Frequently Asked Questions

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

**L2 DOM** operates on a logical tree of `DocumentNode` objects using human-readable paths like `/table[1]/row[2]`, providing validation and safety checks. **L3 Raw XML** works directly with the underlying OpenXML parts (e.g., `/document`, `/styles`) using raw XML and XPath expressions, offering no abstraction but full control over the OOXML package structure.

### Can I accidentally corrupt a document using OfficeCLI's L1 or L2 layers?

No. The **L1 Read** layer is read-only by design, preventing any modification. The **L2 DOM** layer includes validation logic that ensures structural integrity when adding, removing, or modifying nodes. Only the **L3 Raw XML** layer bypasses these safeguards, making it possible to create malformed XML if used incorrectly.

### How do I know which XPath to use with the L3 Raw XML layer?

According to the [`schemas/help/docx/raw.json`](https://github.com/iOfficeAI/OfficeCLI/blob/main/schemas/help/docx/raw.json) documentation, part paths reference specific OpenXML parts (e.g., `/document` for [`document.xml`](https://github.com/iOfficeAI/OfficeCLI/blob/main/document.xml), `/styles` for [`styles.xml`](https://github.com/iOfficeAI/OfficeCLI/blob/main/styles.xml)). For element selection within those parts, use standard XPath 1.0 expressions with the appropriate namespace prefixes (e.g., `//w:p` for Word paragraphs). Use `officecli raw report.docx /document` to inspect the XML structure before writing XPath queries.

### Does OfficeCLI support the same three-layer architecture for Excel and PowerPoint files?

Yes. The `IDocumentHandler` interface is implemented consistently across [`WordHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.cs), [`ExcelHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ExcelHandler.cs), and [`PowerPointHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/PowerPointHandler.cs). While the specific DOM node types and part paths differ between formats (e.g., `/worksheet[1]/row[2]` for Excel vs `/slide[1]/shape[2]` for PowerPoint), the L1/L2/L3 abstraction pattern and command syntax remain identical across all Office document types.