# OfficeCLI Path-Based Addressing for Document Elements: Complete Technical Guide

> Master OfficeCLI path-based addressing for document elements. This guide shows how to target specific content in .docx, .xlsx, and .pptx files using intuitive syntax.

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

---

**OfficeCLI uses a hierarchical 1-based path syntax like `/slide[1]/shape[2]` or `/body/p[3]/r[1]` to address any element inside .docx, .xlsx, and .pptx files.**

This article explains the path-based addressing system implemented in the iOfficeAI/OfficeCLI repository. Whether you're building AI agents or automating document workflows, understanding this deterministic addressing model is essential for reliable Office document manipulation.

## How Path Syntax Works in OfficeCLI

OfficeCLI treats every element inside a document as a node in a **hierarchical, 1-based address space**. The syntax is intentionally simple for programmatic use.

### Core Path Components

| Syntax | Meaning |
|--------|---------|
| `/` | Root of the document |
| `name[index]` | *name* is the OpenXML local name, *index* (≥ 1) selects the N-th sibling |
| `[@attr=value]` | Attribute selector for stable IDs |
| `!` | Negated attribute value (`[color!=FF0000]`) |
| `:contains(text)` | Full-text match for the selector engine |

Valid path examples include:

- `/slide[1]/shape[2]` — second shape on first PowerPoint slide
- `/body/p[3]/r[1]` — first run in third paragraph of Word document body
- `/Sheet1!A5` — cell A5 in Excel Sheet1
- `/body/p[@paraId=A1B2C3D4]` — Word paragraph with stable ID

## Path Parsing and Navigation Engine

The heart of OfficeCLI path-based addressing lives in [`src/officecli/Core/GenericXmlQuery.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/GenericXmlQuery.cs). Two methods handle all path resolution:

### ParsePathSegments (Lines 33-71)

This method splits path strings into navigable segments. For example, `"/slide[1]/shape[2]"` becomes a list of `(Name, Index?)` tuples.

Key behaviors:

- Validates bracket closure
- Rejects non-numeric indices with `ArgumentException`
- Returns structured segment data for downstream navigation

```csharp
// From GenericXmlQuery.cs L33-L71
// Example transformation:
// Input:  "/slide[1]/shape[2]"
// Output: [("slide", 1), ("shape", 2)]

```

### NavigateByPath (Lines 77-90)

This method walks the OpenXML tree, selecting children matching each segment's local name and 1-based index.

- Returns **null** if any segment cannot be resolved
- null results trigger structured error responses with suggested valid ranges

## Format-Specific Path Handling

### Word Documents ([`WordHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.cs))

The Word handler at [`src/officecli/Handlers/WordHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/WordHandler.cs) calls `ParsePath` directly. At line 404, you'll find:

```csharp
var segments = ParsePath(runPath);

```

Word specifically uses **stable paragraph addressing** via `p[@paraId=...]` (lines 70-76 of [`GenericXmlQuery.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/GenericXmlQuery.cs)). This prevents path drift when documents are edited, ensuring AI agents can reference the same paragraph across multiple commands.

### PowerPoint Presentations ([`PowerPointHandler.Resolve.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/PowerPointHandler.Resolve.cs))

PowerPoint handlers use `GenericXmlQuery.ParsePathSegments` directly at line 173 of [`src/officecli/Handlers/Pptx/PowerPointHandler.Resolve.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/Pptx/PowerPointHandler.Resolve.cs). The resolution logic handles slide and shape hierarchies with automatic index validation.

### Excel Workbooks

Excel uses a compact cell notation: `/Sheet1!B5`. The exclamation mark distinguishes sheet names from element paths, borrowing familiar syntax from spreadsheet applications.

## Mutation Operations via Path Targets

The `CommandBuilder` class ([`src/officecli/CommandBuilder.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/CommandBuilder.cs)) implements `Set` and `Add` operations that:

1. Build appropriate OpenXML elements
2. Parse paths via `ParsePath(...)`
3. Apply targets using `NavigateToElement(...)`

### Attribute Setting with Fallback Chain

`GenericXmlQuery.SetGenericAttribute` (lines 99-132) implements a three-tier fallback:

1. Direct XML attribute assignment
2. Child-element `<attr val="..."/>` creation
3. Typed child element instantiation if needed

This ensures maximum compatibility across different OpenXML schema variations.

## Error Handling and AI-Agent Support

All path-related errors return structured JSON with `--json` flag:

```bash
$ officecli get deck.pptx '/slide[10]' --json

```

```json
{
  "success": false,
  "error": {
    "error": "Slide 10 not found (total: 3)",
    "code": "not_found",
    "suggestion": "Valid Slide index range: 1-3"
  }
}

```

Error codes include: `not_found`, `invalid_value`, `invalid_path`. The automatic suggestion of valid index ranges enables agents to self-correct without human intervention.

## Practical Command Examples

### PowerPoint Workflow

```bash

# Create presentation and add slide

officecli create deck.pptx
officecli add deck.pptx / --type slide --prop title="Quarterly Review"

# Add positioned textbox on first slide

officecli add deck.pptx '/slide[1]' \
  --type shape \
  --prop text="Revenue ↑ 25%" \
  --prop x=2cm --prop y=5cm --prop size=28

# Read shape as JSON

officecli get deck.pptx '/slide[1]/shape[1]' --json

# Update fill color

officecli set deck.pptx '/slide[1]/shape[1]' --prop fill="#FFCC00"

# Reposition element

officecli move deck.pptx '/slide[1]/shape[1]' --to '/slide[1]/placeholder[1]' --after

# Remove element

officecli remove deck.pptx '/slide[1]/shape[1]'

```

### Word Document Editing

```bash

# Replace text in third paragraph's first run

officecli set report.docx '/body/p[3]/r[1]' --prop text="Executive Summary"

```

### Excel Cell Manipulation

```bash

# Set cell value by sheet and address

officecli set data.xlsx '/Sheet1!B5' --prop value="12345"

```

## Key Source Files Reference

| File | Role |
|------|------|
| [`src/officecli/Core/GenericXmlQuery.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/GenericXmlQuery.cs) | Central parser (`ParsePathSegments`) and navigator (`NavigateByPath`) |
| [`src/officecli/Handlers/WordHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/WordHandler.cs) | Word-specific path handling and stable ID emission |
| [`src/officecli/Handlers/Word/WordHandler.Navigation.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/Word/WordHandler.Navigation.cs) | Virtual tables and Word-specific navigation quirks |
| [`src/officecli/Handlers/Pptx/PowerPointHandler.Resolve.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/Pptx/PowerPointHandler.Resolve.cs) | PowerPoint path resolution |
| [`src/officecli/CommandBuilder.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/CommandBuilder.cs) | High-level command construction feeding paths to handlers |

## Summary

- OfficeCLI path-based addressing uses **1-based hierarchical syntax** matching OpenXML structure
- [`GenericXmlQuery.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/GenericXmlQuery.cs) provides the **universal parsing and navigation engine** used across all formats
- **Stable paragraph IDs** in Word prevent path drift during document edits
- **Structured JSON errors** with valid range suggestions enable automatic agent recovery
- The **three-tier attribute setter** handles diverse OpenXML schema patterns

## Frequently Asked Questions

### What happens if a path index is out of range?

OfficeCLI returns a structured error with `code: "not_found"` and a `suggestion` field containing the valid index range. This enables AI agents to detect and correct indexing errors programmatically.

### Can paths use zero-based indexing?

No. OfficeCLI strictly uses **1-based indexing** throughout all path segments. This matches natural human counting and reduces off-by-one errors for non-programmers.

### How does Word handle paragraph reordering?

The Word handler emits paths using stable `paraId` attributes: `/body/p[@paraId=A1B2C3D4]`. These IDs persist across edits, ensuring AI agents reference the same logical paragraph regardless of document position changes.

### Is the path syntax case-sensitive?

Element names in paths are **case-sensitive** and must match OpenXML local names exactly. However, hex color values and some identifiers are compared case-insensitively as shown in the `fill="#FFCC00"` example.