OfficeCLI Layer 3 Raw XML Access: Direct OOXML Manipulation Guide

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

Layer 3 Commands and Implementation

The resident server dispatches Layer 3 verbs through a dedicated command switch in 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

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:

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:

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:

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:


# 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:

officecli validate report.docx

Source Code Implementation Details

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

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, 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 or /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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →