# How to Use Raw XML Access for Advanced OOXML Manipulation in OfficeCLI

> Master advanced OOXML manipulation in OfficeCLI with raw XML access. Use the raw-set command and XPath for powerful, low-level document editing. Bypass high-level API limits.

- Repository: [OfficeAI/OfficeCLI](https://github.com/iofficeai/OfficeCLI)
- Tags: how-to-guide
- Published: 2026-08-07

---

**OfficeCLI exposes a low-level `raw-set` command that lets you edit the underlying Open XML (OOXML) markup of any document part using XPath-based mutations, bypassing the limitations of the high-level typed API.**

OfficeCLI is an open-source command-line interface for automating Microsoft Office documents. When you need to perform operations that the standard `add`, `set`, or `remove` commands cannot express—such as inserting mixed-formatting runs, legacy VML shapes, or complex chart attributes—you can leverage **raw XML access** to manipulate the underlying OOXML parts directly.

## Understanding the Raw-Set Architecture

The `raw-set` command follows a structured pipeline from CLI parsing to XML mutation. According to the iOfficeAI/OfficeCLI source code, the implementation spans four critical components.

### Command Parsing and Dispatch

In [`src/officecli/CommandBuilder.Raw.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/CommandBuilder.Raw.cs) (lines 60-74), the `BuildRawSetCommand` method defines the CLI syntax: `officecli raw-set <file> <part> --xpath <xp> --action <act> [--xml <fragment>]`. This parses arguments into a `ResidentRequest` that identifies the target document part via a *zip-uri* (e.g., [`/docProps/core.xml`](https://github.com/iOfficeAI/OfficeCLI/blob/main//docProps/core.xml) or `/document`).

### Handler-Specific Implementations

Each document type implements a specialized `RawSet` method:

- **WordHandler.RawSet** ([`src/officecli/Handlers/WordHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/WordHandler.cs), lines 1569-1625): Handles Word-specific fast-paths for styles, body paragraphs, and headers/footers, with fallback to generic DOM re-serialization.
- **PowerPointHandler.RawSet** ([`src/officecli/Handlers/PowerPointHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/PowerPointHandler.cs), lines 262-267): Mirrors the Word implementation for slide, master, and notes parts.
- **ExcelHandler.RawSet** ([`src/officecli/Handlers/ExcelHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/ExcelHandler.cs), lines 45-48): Processes worksheets, charts, and drawing parts using the same pattern.

### Shared XML Execution Engine

All handlers delegate zip-uri based requests to `RawXmlHelper.Execute`, which applies the specified **XPath**, **action**, and **XML fragment** to the identified part. This shared helper ensures consistent behavior across document types while allowing handlers to intercept well-known semantic paths for optimization.

## When to Use Raw XML Access vs. High-Level Commands

Use **raw XML access** when the high-level SDK model does not expose a particular attribute or structure. Specific scenarios include:

- **Fine-grained styling**: Applying distinct `<w:rPr>` attributes to different runs within a single paragraph.
- **Legacy VML elements**: Inserting Office 2003 compatibility shapes using `mc:Fallback` tags.
- **Complex chart layouts**: Modifying unsupported attributes like `<c:ln>/<a:gradFill>` in chart definitions.
- **Binary embedding**: Attaching images or OLE objects via base-64 data URIs using the `embed-binary` action.

For standard operations like adding simple paragraphs or setting basic properties, prefer the high-level commands to avoid XML validation errors.

## Raw XML Manipulation by Document Type

### Word Documents (DOCX)

The `WordHandler.RawSet` method validates the document before mutation using `ReportNewErrorsAsWarnings`, then dispatches based on the part path. For well-known paths like `/document`, `/styles`, or `/header[n]`, it uses optimized fast-paths; otherwise, it falls back to the generic XPath executor.

### PowerPoint Presentations (PPTX)

`PowerPointHandler.RawSet` handles slides, masters, and notes pages. You can manipulate `p:cSld` (common slide data), `p:spTree` (shape trees), or individual shape properties using the same `--xpath` and `--action` parameters as Word.

### Excel Workbooks (XLSX)

`ExcelHandler.RawSet` processes worksheet XML, chart spaces (`c:chartSpace`), and drawing parts. This enables modifications to chart definitions and cell formatting that exceed the capabilities of the typed model.

## Practical Code Examples

Below are three production-ready scenarios demonstrating **raw XML access** for advanced OOXML manipulation.

### Insert a Mixed-Format Textbox in Word

This example inserts a paragraph with bold, italic, colored, underlined, and strikethrough text before the document's section properties:

```bash
officecli raw-set textbox.docx /document \
  --xpath "//w:body/w:sectPr" \
  --action insertbefore \
  --xml '
<w:p>
  <w:r><w:rPr><w:b/></w:rPr><w:t>Bold</w:t></w:r>
  <w:r><w:rPr><w:i/></w:rPr><w:t>Italic</w:t></w:r>
  <w:r><w:rPr><w:color w:val="FF0000"/><w:sz w:val="20"/></w:rPr><w:t>Red small</w:t></w:r>
  <w:r><w:rPr><w:u w:val="single"/></w:rPr><w:t>Underline</w:t></w:r>
  <w:r><w:rPr><w:strike/></w:rPr><w:t>Strikethrough</w:t></w:r>
</w:p>'

```

*Implementation reference*: [`CommandBuilder.Raw.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/CommandBuilder.Raw.cs) (lines 68-74) builds the command; `WordHandler.RawSet` (lines 1569-1625) executes the mutation.

### Add Gradient Background and Shape to PowerPoint

First, prepend a gradient background to slide 1:

```bash
officecli raw-set presentation.pptx /slide[1] \
  --xpath "//p:cSld" \
  --action prepend \
  --xml '
<p:bg>
  <p:bgPr>
    <a:gradFill rotate="5400000">
      <a:gsLst>
        <a:gs pos="0"><a:srgbClr val="FF7F50"/></a:gs>
        <a:gs pos="100000"><a:srgbClr val="1E90FF"/></a:gs>
      </a:gsLst>
    </a:gradFill>
  </p:bgPr>
</p:bg>'

```

Then append a rectangle shape with text:

```bash
officecli raw-set presentation.pptx /slide[1] \
  --xpath "//p:cSld/p:spTree" \
  --action append \
  --xml '
<p:sp>
  <p:nvSpPr>
    <p:cNvPr id="4" name="Rectangle"/>
    <p:cNvSpPr/>
    <p:nvPr/>
  </p:nvSpPr>
  <p:spPr>
    <a:xfrm>
      <a:off x="1524000" y="1524000"/>
      <a:ext cx="3048000" cy="1524000"/>
    </a:xfrm>
    <a:prstGeom prst="rect"><a:avLst/></a:prstGeom>
    <a:solidFill><a:srgbClr val="FFFF00"/></a:solidFill>
    <a:ln w="12700"><a:solidFill><a:srgbClr val="000000"/></a:solidFill></a:ln>
  </p:spPr>
  <p:txBody><a:bodyPr/><a:lstStyle/><a:p><a:r><a:t>Demo</a:t></a:r></a:p></p:txBody>
</p:sp>'

```

*Implementation reference*: `PowerPointHandler.RawSet` (lines 262-267) processes these requests using the same underlying machinery as Word.

### Replace Chart XML in Excel

Replace the entire chart space definition for the second chart in a workbook:

```bash
officecli raw-set report.xlsx '/Analysis/chart[2]' \
  --xpath "/c:chartSpace" \
  --action replace \
  --xml '
<c:chartSpace xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart">
  <!-- Custom chart definition goes here -->
</c:chartSpace>'

```

*Implementation reference*: `ExcelHandler.RawSet` (lines 45-48) forwards to `RawXmlHelper.Execute` for the actual XML substitution.

## Summary

- **Raw XML access** in OfficeCLI is exposed through the `raw-set` command, which bypasses the high-level API to manipulate OOXML parts directly.
- The architecture routes commands through [`CommandBuilder.Raw.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/CommandBuilder.Raw.cs) to document-specific handlers ([`WordHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.cs), [`PowerPointHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/PowerPointHandler.cs), [`ExcelHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ExcelHandler.cs)) and ultimately to `RawXmlHelper.Execute`.
- Use **zip-uris** (e.g., `/document`, `/slide[1]`) to identify target parts, and **XPath expressions** to locate specific XML nodes for insertion, appending, prepending, or replacement.
- This approach enables advanced scenarios like mixed-formatting textboxes, VML fallbacks, gradient chart fills, and binary embedding that are impossible with standard commands.

## Frequently Asked Questions

### What is the difference between raw-set and the standard set command in OfficeCLI?

The standard `set` command operates on the typed SDK model (e.g., setting paragraph text or table values), while `raw-set` operates directly on the underlying OOXML markup using XPath. Use `raw-set` when you need to modify attributes or elements that the high-level API does not expose, such as specific drawingML attributes or legacy compatibility tags.

### How does OfficeCLI validate documents when using raw XML access?

Before applying mutations, handlers like `WordHandler.RawSet` establish an error baseline and then invoke `ReportNewErrorsAsWarnings` after the operation. This ensures that only new validation warnings introduced by your XML fragment are reported, helping you identify malformed markup while preserving the document's original validity state.

### Can I use raw-set to modify any part of an Office document?

Yes, you can target any part using a *zip-uri* (e.g., [`/docProps/core.xml`](https://github.com/iOfficeAI/OfficeCLI/blob/main//docProps/core.xml), [`/word/document.xml`](https://github.com/iOfficeAI/OfficeCLI/blob/main//word/document.xml), or [`/ppt/slides/slide1.xml`](https://github.com/iOfficeAI/OfficeCLI/blob/main//ppt/slides/slide1.xml)). The `RawXmlHelper.Execute` method handles the package-level addressing, while document-specific handlers provide optimized fast-paths for common semantic locations like `/document` or `/styles`.

### What actions are supported by the raw-set command?

The command supports `insertbefore`, `prepend`, `append`, `replace`, and `embed-binary` actions. The `embed-binary` action is particularly useful for inserting base-64 encoded images or OLE objects directly into the XML stream, as implemented in the `RawEmbedBinary` method within `WordHandler`.