# OfficeCLI Layer 3 Raw XML Access: Direct OOXML Manipulation Guide

> Unlock OfficeCLI Layer 3 Raw XML Access for direct OOXML manipulation. Directly edit document parts with XPath when higher-level commands fall short. Master your documents.

- Repository: [OfficeAI/OfficeCLI](https://github.com/iofficeai/OfficeCLI)
- Tags: deep-dive
- Published: 2026-07-18

---

**Layer 3 (Raw XML Access) in OfficeCLI provides direct XPath-based manipulation of OOXML document parts when higher-level semantic commands cannot express the required changes.**

The **iOfficeAI/OfficeCLI** repository implements a three-layer architecture for document automation, where Layer 3 serves as the universal fallback for advanced users who need to inject custom elements, tweak obscure attributes, or operate on document parts lacking dedicated DSL support.

## What Is Layer 3 Raw XML Access in OfficeCLI?

**Layer 3 Raw XML Access** is the lowest abstraction level in OfficeCLI's architecture, allowing you to read and write raw OOXML using XPath expressions. When the high-level **L1 (Read)** and **L2 (DOM)** commands prove insufficient—such as when inserting custom XML parts, modifying obscure wordprocessingML attributes, or manipulating relationships directly—Layer 3 provides the escape hatch to the underlying XML.

According to the repository's architecture documentation, Layer 3 is invoked through four primary commands: `raw`, `raw-set`, `add-part`, and `validate`. These commands bypass the semantic wrappers and interact directly with the document's ZIP package and XML streams.

## The Three-Layer Architecture Overview

OfficeCLI organizes its functionality into distinct abstraction tiers:

- **L1 (Read)**: Semantic, high-level views (text, outline, statistics) via the `view` command
- **L2 (DOM)**: Structured element operations (get, query, set, add, remove, move, swap) for manipulating document objects
- **L3 (Raw XML)**: Direct XPath access for universal coverage when L2 cannot express a specific change

*Source: [iOfficeAI/OfficeCLI README.md](https://github.com/iOfficeAI/OfficeCLI/blob/main/README.md#L45-L50)*

## Layer 3 Commands and Implementation

The resident server dispatches Layer 3 verbs through a dedicated command switch in [`src/officecli/ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/ResidentServer.cs) (lines 1115–1122). When processing these commands, the server first promotes the document to an editable state, executes the raw operation, then triggers `NotifyWatchFullRefresh()` for any live document watchers.

### raw: Inspecting OOXML Structure

The `raw` command performs pure-read operations on document parts, returning the raw XML without modification. This allows inspection of any OOXML part using XPath selectors to locate specific elements before attempting modifications.

### raw-set: Modifying XML with XPath

**`raw-set`** is the primary mutation command for Layer 3, supporting several action types:

- **`--xpath`**: Target location using 1-based XPath notation (e.g., `//w:p[1]`)
- **`--action`**: One of `append`, `prepend`, `insertbefore`, `insertafter`, `replace`, `remove`, or `setattr`
- **`--xml`**: The XML snippet to insert or replace (required for applicable actions)

Before execution, the command invokes `PromoteToEditable()` to ensure the document is writable, applies the XPath-based modification, then notifies watchers of the full refresh.

*Source: [SKILL.md – L3 Raw XML section](https://github.com/iOfficeAI/OfficeCLI/blob/main/SKILL.md#L44-L55)*

### add-part: Creating Custom OOXML Parts

The **`add-part`** command generates brand-new OOXML parts (such as custom relationships or hidden `/customXml` entries) and returns their `rId` identifiers. This is essential for embedding binary assets, custom data islands, or specialized markup that the core CLI does not expose through higher-level APIs.

### validate: Ensuring Document Integrity

After performing raw XML modifications, the **`validate`** command runs the OfficeCLI OOXML validator to surface schema errors, missing relationships, or namespace issues. This verification step helps maintain document health despite low-level edits that bypass standard safety checks.

## Practical Layer 3 Usage Examples

### View Raw Slide XML in PowerPoint

Inspect the exact XML structure of the first slide to understand element hierarchy before modification:

```bash
officecli raw deck.pptx '/slide[1]'

```

### Append Custom Paragraph to Word Document

Inject a new paragraph at the end of the document body using the `append` action:

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

```

### Replace Spreadsheet Cell Content

Directly swap XML content in a specific Excel cell without using the L2 table API:

```bash
officecli raw-set budget.xlsx /xl/worksheets/sheet1.xml \
  --xpath "(//x:table/x:tr[1]/x:tc[1]/x:p)[1]" \
  --action replace \
  --xml '<w:p><w:r><w:t>New Value</w:t></w:r></w:p>'

```

### Create Custom XML Part with Binary Data

First generate a new part to obtain an `rId`, then embed base64-encoded binary data:

```bash

# Create new part and capture rId

custom_rid=$(officecli add-part report.docx /customXml)

# Embed binary data into the custom part

officecli raw-set report.docx "/customXml/${custom_rid}" \
  --xpath "/" \
  --action replace \
  --xml '<customData xmlns="urn:custom"><image format="png">iVBORw0KGgo…</image></customData>'

```

### Validate Document After Raw Modifications

Check for schema violations introduced by low-level edits:

```bash
officecli validate report.docx

```

## Source Code Implementation Details

The Layer 3 implementation spans several key files in the iOfficeAI/OfficeCLI repository:

- **[`src/officecli/ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/ResidentServer.cs) (lines 1115–1122)**: Contains the command dispatch switch routing `raw`, `raw-set`, and `add-part` verbs to their respective handlers
- **`src/officecli/Handlers/WordHandler.*`**: Demonstrates internal usage of `raw-set` for Word-specific features like bookmark insertion and style handling
- **[`src/officecli/Handlers/Pptx/PowerPointHandler.StyleList.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/Pptx/PowerPointHandler.StyleList.cs) (line 119)**: Contains the implementation comment "Layer 3: master txStyles" illustrating raw XML employment for PowerPoint styling
- **[`src/officecli/Handlers/Word/WordHandler.Add.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/Word/WordHandler.Add.cs) (line 257)**: Shows fallback to `raw-set` for unsupported element types such as `altChunk`

## When to Use Layer 3 vs. L1/L2

Use **Layer 3 Raw XML Access** when:

- You must modify obscure OOXML attributes not exposed by the DOM layer
- You need to insert custom elements or non-standard markup
- Working with document parts that have no dedicated DSL in L2
- Embedding binary assets or custom XML data islands requires precise part creation
- L2's semantic commands cannot represent the specific structural change needed

Reserve **L1 (Read)** for document inspection and **L2 (DOM)** for standard structural operations like paragraph insertion or table manipulation, as these provide safer, higher-level abstractions.

## Summary

- **Layer 3** provides direct XPath-based access to raw OOXML when higher-level commands are insufficient
- The four primary commands are **`raw`**, **`raw-set`**, **`add-part`**, and **`validate`**
- The resident server promotes documents to editable state, executes raw operations, and refreshes watchers via `NotifyWatchFullRefresh()`
- **XPath actions** include `append`, `prepend`, `insertbefore`, `insertafter`, `replace`, `remove`, and `setattr`
- Always run **`validate`** after raw modifications to ensure OOXML schema compliance

## Frequently Asked Questions

### What is the difference between Layer 2 DOM and Layer 3 Raw XML in OfficeCLI?

**Layer 2 DOM** provides structured, semantic operations on document elements (like adding paragraphs or querying tables) with built-in safety checks, while **Layer 3 Raw XML** exposes the underlying OOXML for direct XPath manipulation when the DOM API cannot express specific changes. Layer 3 requires you to construct valid XML snippets and understand OOXML schema details.

### How does OfficeCLI handle document editing permissions for raw XML modifications?

According to the source code in [`ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ResidentServer.cs), the system calls `PromoteToEditable()` before executing any `raw-set` or `add-part` operation. This ensures write access is acquired before mutation, then triggers `NotifyWatchFullRefresh()` after changes complete to update any live document watchers.

### Can I use Layer 3 commands to modify any OOXML part in an Office document?

Yes, Layer 3 commands can target any part within the OOXML package, including standard parts like [`/word/document.xml`](https://github.com/iOfficeAI/OfficeCLI/blob/main//word/document.xml) or [`/xl/worksheets/sheet1.xml`](https://github.com/iOfficeAI/OfficeCLI/blob/main//xl/worksheets/sheet1.xml), as well as custom parts created via `add-part`. You specify the target part in the command arguments and use XPath selectors to navigate the specific XML structure.

### What are common pitfalls when using raw-set in OfficeCLI?

Common issues include using 1-based XPath indexing incorrectly (OfficeCLI uses 1-based positions, not 0-based), introducing namespace errors in injected XML, and creating invalid OOXML structures that pass initial insertion but fail schema validation. Always use the **`validate`** command after raw modifications to catch missing relationships or malformed elements before saving.