# OfficeCLI Raw XML Command for XPath Access: Direct OpenXML Manipulation Guide

> Unlock OfficeCLI raw XML commands for direct OpenXML manipulation. Use XPath expressions to precisely read, edit, and validate Office documents bypassing the object model.

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

---

**OfficeCLI raw XML commands expose a low-level interface that lets you read, edit, and validate Office documents using standard XPath expressions, bypassing the higher-level object model for precise control over underlying OpenXML parts.**

The [OfficeCLI](https://github.com/iOfficeAI/OfficeCLI) open-source tool provides powerful `raw` and `raw-set` subcommands for direct XML manipulation. These commands target specific OpenXML parts within Word, Excel, and PowerPoint files, enabling precision edits that aren't exposed through standard object-model methods. This article covers the complete implementation, from the core `RawXmlHelper` class to practical terminal examples.

## How OfficeCLI Raw XML Commands Work

The raw XML layer consists of three integrated components that transform XPath expressions into document modifications.

### Core Architecture

| Component | Role | Source File |
|-----------|------|-------------|
| **RawXmlHelper** | Loads XML parts, resolves namespaces, executes XPath queries, and persists changes | [`src/officecli/Core/RawXmlHelper.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/RawXmlHelper.cs) |
| **CommandBuilder.Raw** | Defines `raw` and `raw-set` subcommands, parses `--xpath` options, routes to helper | [`src/officecli/CommandBuilder.Raw.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/CommandBuilder.Raw.cs) |
| **CLI binary** | Orchestrates document opening, part streaming, and formatted output | `src/officecli/officecli.csproj` |

In [`RawXmlHelper.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/RawXmlHelper.cs), the helper class constructs an `XmlNamespaceManager` from each part's declared namespaces. This automatic resolution lets you use standard Office prefixes (`w:` for WordprocessingML, `a:` for DrawingML, `r:` for relationships) without manual prefix declarations.

The execution flow follows five steps:

1. Open the target document (`.docx`, `.xlsx`, `.pptx`)
2. Locate the requested part via path notation (`/document`, `/slide[2]/shape[3]`)
3. Build namespace manager from part declarations
4. Execute XPath against the `XDocument`
5. Return nodes (for `raw`) or write modified XML back to the package (for `raw-set`)

### XPath Semantics in OfficeCLI

The **OfficeCLI raw XML command for XPath access** uses **1-based indexing**, consistent with XML standards and OfficeCLI's path model. The expression `/body/p[2]` selects the second paragraph, not the third.

Supported selectors include:

- **Wildcard nodes** (`*`) matching any element
- **Attribute accessors** (`@`) for property extraction
- **Predicate functions** like `[last()]` for dynamic positioning

Error handling surfaces through [`OutputFormatter.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/OutputFormatter.cs), providing actionable messages such as *"XPath matched no elements"* or *"Expression must evaluate to a node-set"* rather than raw .NET exceptions.

## OfficeCLI Raw XML Command Syntax

### Command Structure

```bash
officecli raw <FILE> <PART-PATH> --xpath "<EXPRESSION>" [OPTIONS]
officecli raw-set <FILE> <PART-PATH> --xpath "<EXPRESSION>" --value "<XML-FRAGMENT>" [OPTIONS]

```

Required parameters:
- `<FILE>` — path to Office document
- `<PART-PATH>` — logical path to OpenXML part (`/document`, `/slide[1]`, `/sheet[Sheet1]`)
- `--xpath` — XPath 1.0 expression targeting nodes within that part

`raw-set` additionally requires:
- `--value` — replacement XML string (empty string deletes matched nodes)

Optional flags:
- `--json` — output structured JSON for machine parsing
- `--pretty` — formatted XML output (default for terminal)

## Practical XPath Examples for Office Documents

### View XML Structure with `raw`

Extract the second row, third cell's first paragraph from the first table in a Word document:

```bash
officecli raw document.docx /document \
    --xpath "//w:tbl[w:tr][1]/w:tr[2]/w:tc[3]/w:p"

```

This targets:
- `//w:tbl[w:tr][1]` — first table containing rows
- `/w:tr[2]` — second row (1-based)
- `/w:tc[3]` — third cell
- `/w:p` — paragraph element

The command outputs the matching `<w:p>` element or a list when multiple nodes match.

### Modify Table Properties with `raw-set`

Update the first table's width specification:

```bash
officecli raw-set document.docx /document \
    --xpath "//w:tbl[1]/w:tblPr/@w:tblW" \
    --value "<w:tblW w:w=\"5000\" w:type=\"dxa\"/>"

```

The XPath selects the `w:tblW` attribute node. The `--value` provides complete replacement XML. After execution, the document archive updates with the new width while preserving all relationships and content.

### Append Rows to Tables

Insert a new row at the end of the first table:

```bash
officecli raw-set document.docx /document \
    --xpath "(//w:tbl)[1]/w:tr[last()]" \
    --value "<w:tr><w:tc><w:p><w:r><w:t>New row</w:t></w:r></w:p></w:tc></w:tr>"

```

The `[last()]` predicate dynamically targets the final row. When `raw-set` receives a container node target and valid child XML, it appends the fragment as a new child element.

### Delete Nodes via Empty Value

Remove all empty paragraphs (no run children) from the document body:

```bash
officecli raw-set document.docx /document \
    --xpath "//w:p[not(w:r)]" \
    --value ""

```

The `[not(w:r)]` predicate filters paragraphs lacking text runs. An empty `--value` triggers node removal rather than replacement.

### Machine-Readable JSON Output

Extract image relationship IDs from PowerPoint slide 2:

```bash
officecli raw presentation.pptx /slide[2] \
    --xpath "//a:blip/@r:embed" \
    --json

```

Returns a JSON array of `r:embed` attribute values, enabling downstream automation scripts to process media references programmatically.

## Namespace Handling in OfficeCLI Raw Commands

The [`RawXmlHelper.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/RawXmlHelper.cs) implementation eliminates manual namespace management. Common Office XML prefixes resolve automatically:

| Prefix | Namespace | Document Type |
|--------|-----------|---------------|
| `w:` | `http://schemas.openxmlformats.org/wordprocessingml/2006/main` | Word |
| `a:` | `http://schemas.openxmlformats.org/drawingml/2006/main` | Drawing (all apps) |
| `r:` | `http://schemas.openxmlformats.org/officeDocument/2006/relationships` | Relationships |
| `p:` | `http://schemas.openxmlformats.org/presentationml/2006/main` | PowerPoint |
| `x:` | `http://schemas.openxmlformats.org/spreadsheetml/2006/main` | Excel |

This automatic resolution means you can write `//w:tbl` directly rather than declaring `w` explicitly in each command.

## Error Handling and Diagnostics

[`OutputFormatter.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/OutputFormatter.cs) translates technical XPath failures into actionable guidance:

- **"XPath matched no elements"** — Verify part path and expression syntax
- **"Expression must evaluate to a node-set"** — Ensure query returns elements/attributes, not boolean or number
- **"Multiple nodes matched but single node expected"** — Add predicates to narrow selection
- **"Invalid XML in --value"** — Check fragment well-formedness against target schema

These messages surface through stderr with exit codes distinguishing parsing failures (exit 2) from runtime errors (exit 1).

## Integration with Higher-Level Operations

The [`WordHandler.Navigation.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.Navigation.cs) file demonstrates how OfficeCLI uses raw XML commands internally. Table cell navigation, for example, falls back to `RawXmlHelper` when high-level `set` commands cannot address specific structural positions. This hybrid approach ensures the CLI covers edge cases without exposing complexity to typical workflows.

## Summary

- **OfficeCLI raw XML commands** provide direct XPath access to OpenXML document parts through `raw` (read) and `raw-set` (write) operations
- The [`RawXmlHelper.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/RawXmlHelper.cs) class manages namespace resolution, query execution, and change persistence
- **1-based indexing** applies to all positional predicates, matching XML standards
- **Automatic namespace handling** supports standard prefixes (`w:`, `a:`, `r:`) without manual declaration
- Empty `--value` strings in `raw-set` delete matched nodes
- The `--json` flag enables structured output for automation pipelines

## Frequently Asked Questions

### What XPath version does OfficeCLI support?

OfficeCLI implements **XPath 1.0** as provided by .NET's `System.Xml.XPath` namespace. This covers node selection, predicates, attribute accessors, and functions like `last()` and `position()`. XPath 2.0+ features such as sequences and `for` expressions are not supported.

### Can I use OfficeCLI raw commands on password-protected documents?

No. The raw XML layer requires standard ZIP archive access to OpenXML parts. Document encryption prevents this access. Remove protection first through Office applications or the `officecli decrypt` command (if implemented in your version) before using `raw` or `raw-set`.

### How do I target specific slides, sheets, or document sections?

Use the **part path** syntax before `--xpath`: `/slide[3]` for PowerPoint slide 3, `/sheet[Sheet1]` for Excel named sheets, `/document` for Word main document part. These paths map to specific `.xml` files within the ZIP-based Office package structure.

### What happens if my `--value` XML fragment uses undeclared namespaces?

`RawXmlHelper` validates fragment well-formedness but does not automatically inherit namespace declarations from the target context. Include full namespace declarations in fragments when targeting elements outside the default namespace, or use prefixes already declared in the target part.