Path-Based Element Addressing in OfficeCLI: A Complete Guide to Stable Document Navigation

OfficeCLI uses POSIX-style paths with 1-based indexes and named predicates to address any element in Word, PowerPoint, or Excel documents, enabling scriptable, mutation-safe automation.

Path-based element addressing in OfficeCLI provides a unified way to navigate and manipulate Office documents without dealing with raw XML or complex XPath expressions. Every mutable object—slides, shapes, tables, cells, textboxes—becomes a node in a virtual tree reachable through a stable, human-readable path. This design powers both read queries and destructive mutations across all three supported formats.

How Path Resolution Works in the OfficeCLI Server

The addressing system centers on ResidentServer.cs, where incoming CLI commands are parsed and dispatched. When a command arrives, the server extracts the target path and delegates resolution to the appropriate document handler:

var path = req.GetArg("path", "/");               // [/src/officecli/ResidentServer.cs#L1932]
var node = _handler.Get(path, depth);              // [/src/officecli/ResidentServer.cs#L1934]

The _handler.Get() method traverses the document tree token by token, matching element names against the format-specific grammar implemented in WordHandler, PowerPointHandler, or ExcelHandler. Each token can include:

  • A local element name: slide, shape, table, cell, textbox, p (paragraph)
  • An optional 1-based index: [2], [last()]
  • An optional named predicate: [@name=HeroTitle], [@id=chart-001]

Before any mutation executes, the server validates scoping through MutationSelectorGuard:

OfficeCli.Core.MutationSelectorGuard.EnsureScoped(path, "set"); // [/src/officecli/ResidentServer.cs#L2128]

This guard ensures that commands like add, set, remove, and move cannot accidentally target multiple elements or escape their intended document region.

Path Syntax and Grammar Rules

Basic Structure

Paths follow filesystem conventions but with Office-specific semantics:


/document-root/element[index]/child[@predicate]

The root is always /, representing the document container. From there, each segment drills deeper into the structure.

Positional vs. Named Addressing

OfficeCLI supports two addressing strategies with different stability guarantees:

Approach Syntax Stability Use Case
Positional index /slide[3]/shape[2] Fragile—breaks when elements shift Quick scripts, temporary operations
Named predicate /slide[@name=Intro]/shape[@id=logo] Stable—survives reordering and deletion Production automation, CI/CD pipelines

Named elements are created by setting the name or id property during an add operation, then referenced later via [@name=...] or [@id=...].

Special Index Functions

The parser recognizes two special functions for dynamic positioning:

  • [last()]: Selects the final element in a collection
  • [*]: Expands to all children (used in queries)

These function identically across Word, PowerPoint, and Excel handlers.

Practical Code Examples by Document Type

PowerPoint: Stable Shape Addressing with Named Predicates

Create a named shape on a new slide, then modify it reliably even after other edits:


# Create a new slide and capture its assigned path

slide=$(officecli add deck.pptx / --type slide)

# Add a rectangle with a stable name for later reference

officecli add deck.pptx "$slide" \
    --type shape --prop preset=rect --prop name=HeroTitle \
    --prop text="Launch Goal"

# Later in the script—or a completely different session—update by name

officecli set deck.pptx "/slide[1]/shape[@name=HeroTitle]" \
    --prop fill=ff3366

The @name predicate survives slide reordering, intermediate deletions, and new insertions. See [/skills/officecli-pptx/SKILL.md#L308] for the complete naming convention documentation.

Excel: Direct Cell and Sheet Addressing

Reference worksheets by their display name and cells by standard address notation:


# Get the value of cell B5 on the "Q1" sheet

officecli get sales.xlsx "/Q1/cell[B5]"

The handler interprets cell[B5] as the Excel address B5 relative to sheet Q1. This works uniformly across .xlsx files regardless of underlying XML structure.

Word: Textbox Manipulation with Path Chaining

Add, reposition, and populate a textbox using path variables:


# Add a textbox at the document body root

tb=$(officecli add report.docx /body --type textbox)

# Move it to follow the first paragraph

officecli move report.docx "$tb" "/body/p[2]"

# Add content inside the textbox—the variable still references the correct node

officecli add report.docx "$tb/p[1]" --type paragraph --prop text="Executive Summary"

The tb variable receives the concrete resolved path (e.g., /body/textbox[3]) after the add operation, enabling reliable chaining. Full script: [/examples/word/textbox.md#L25].

Batch Operations with Wildcards

Query all elements matching a pattern:


# List every shape on the most recently added slide

officecli get deck.pptx "/slide[last()]/shape[*]"

# Remove the third slide regardless of its current content

officecli remove deck.pptx "/slide[3]"

Indexes are always evaluated against the current document state, not the state at script start. This prevents off-by-one errors during batch modifications.

Mutation Safety and Scope Enforcement

OfficeCLI's path-based element addressing includes built-in protections against dangerous operations. The MutationSelectorGuard ([/src/officecli/ResidentServer.cs#L2128]) validates that:

  • set, remove, and move commands resolve to exactly one target element
  • Wildcard selectors [*] are rejected for mutations
  • Paths without explicit scope cannot modify document-wide properties

This design prevents accidental bulk changes and makes scripts more predictable in automated environments.

Architecture: Key Components

Understanding the implementation helps troubleshoot path resolution failures and extend the system:

Component Responsibility Source Location
ResidentServer HTTP request handling, path argument extraction, handler dispatch src/officecli/ResidentServer.cs ([L1932-L1934], [L2128])
Document handlers (WordHandler, PowerPointHandler, ExcelHandler) Per-format path grammar, node tree traversal, element name mapping src/officecli/Handlers/*.cs
MutationSelectorGuard Pre-mutation validation, scope enforcement, error messaging src/officecli/ResidentServer.cs ([L2076], [L2128], [L2390])
Skill documentation Naming conventions, stable addressing patterns, format-specific examples skills/officecli-pptx/SKILL.md ([L308])
Example scripts Real-world path patterns for common automation tasks examples/word/textbox.md ([L25]), examples/ppt/tables/tables-nested.md ([L15])

The README explicitly lists path-based addressing as a first-class capability at [L415], reflecting its central role in the OfficeCLI design.

Design Philosophy: Why Not XPath?

OfficeCLI deliberately uses a simplified path syntax instead of full XPath:

  • No namespaces: Office Open XML uses multiple XML namespaces that complicate XPath expressions
  • No functions: Beyond last() and index predicates, the grammar stays simple
  • 1-based indexing: Matches human document conventions and Office UI numbering
  • Local names only: Element types are format-specific but unqualified (shape not p:sp)

This trade-off sacrifices some flexibility for massive gains in script readability and cross-format consistency. The same mental model works for .docx, .pptx, and .xlsx files.

Summary

  • Path-based element addressing in OfficeCLI uses POSIX-style paths with 1-based indexes and named predicates to locate any document element
  • The ResidentServer in src/officecli/ResidentServer.cs orchestrates path extraction, resolution via document handlers, and mutation scoping via MutationSelectorGuard
  • Named predicates (@name=, @id=) provide stable addressing that survives document structure changes, while positional indexes are fragile but convenient
  • All three Office formats share the same path syntax, with format-specific handlers implementing the element name grammar
  • Mutation commands enforce single-element scope, preventing accidental bulk changes

Frequently Asked Questions

Can I use XPath expressions in OfficeCLI paths?

No. OfficeCLI uses a simplified, element-local path syntax instead of full XPath. This eliminates XML namespace complexity while preserving the essential navigation patterns. The supported grammar includes: /element[index], [@name=value] predicates, and the [last()] function.

What happens if multiple elements match a mutation path?

The MutationSelectorGuard rejects the command with a scope error. Mutations require unambiguous single-element targets. For operations affecting multiple elements, use a query loop in your shell script to process items individually.

How do I make my paths resilient to document changes?

Assign stable names or IDs during element creation, then reference them with predicates:

officecli add deck.pptx /slide[1] --type shape --prop name=PersistentLogo
officecli set deck.pptx "/slide[1]/shape[@name=PersistentLogo]" --prop visible=false

Named elements survive reordering, deletion of sibling elements, and document saves across sessions.

Does path indexing start at 0 or 1?

OfficeCLI uses 1-based indexing to match human conventions and Office application interfaces. /slide[1] is the first slide, /table/row[1] is the first row. The [last()] function retrieves the final element without knowing the total count.

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 →