OfficeCLI Path-Based Addressing Syntax Explained: XPath-Inspired Navigation for Office Documents

OfficeCLI uses a flat, XPath-inspired path-based addressing syntax that lets you target any element in PowerPoint, Word, or Excel documents using simple slash-delimited strings with positional indexes, attribute selectors, and the last() function.

The OfficeCLI path-based addressing syntax provides a uniform way to locate and manipulate elements across different Microsoft Office formats without dealing with raw XML. According to the iOfficeAI/OfficeCLI source code, this addressing model treats documents as hierarchical trees where every addressable element—from slides to table cells—can be referenced with a stable text path.

Core Components of the Addressing Syntax

The parser implements a lightweight tokenization system that recognizes four fundamental building blocks. Unlike full XPath engines, OfficeCLI does not handle namespaces or complex predicates, making command-line usage predictable and fast.

Root and Element Names

Every path begins with the root symbol /, which represents the document's read-only top-level container. From there, you traverse the hierarchy using element local names such as slide, shape, table, sheet, or body.

In skills/officecli-pptx/SKILL.md, the implementation specifies that presentation, document, and workbook containers are addressed implicitly at /, meaning you never type /presentation but instead start with the child element directly.


# Address the first slide in a PowerPoint file

officecli get "$FILE" "/slide[1]"

# Address the document body in Word

officecli get "$FILE" "/body"

Positional Indexes

Use 1-based numeric indexes in square brackets to select the Nth occurrence of an element type. Positional addressing is volatile—removing or reordering elements shifts subsequent indexes.

As documented in examples/ppt/tables/tables-nested.md, deep nesting requires chaining indexes:


# Target the first shape inside the second slide

officecli set "$FILE" "/slide[2]/shape[1]" --prop fill=blue

Attribute Selectors

For stable, automation-friendly addressing, use [@name=...] or [@id=...] to filter by persistent attributes. The name attribute is recommended for scripts because it survives structural changes that would break positional references.

The skills/officecli-pptx/SKILL.md file emphasizes that name-based selectors create addresses resilient to reordering:


# Create a shape with a stable name

officecli add "$FILE" "/slide[1]" --type shape --prop name=HeroTitle

# Modify it later by name, regardless of its current position

officecli set "$FILE" "/slide[1]/shape[@name=HeroTitle]" --prop text="Updated"

Special Functions

The parser currently supports only one function: last(). When used inside brackets, it evaluates to the most recently added element of that type, which is useful immediately after creation operations.

From skills/officecli-pptx/SKILL.md, the last() function implementation allows dynamic addressing without knowing the exact count:


# Add a new slide and immediately set its title

officecli add "$FILE" --type slide
officecli set "$FILE" "/slide[last()]" --prop title="New Slide"

Format-Specific Addressing Patterns

While the syntax is uniform, each Office format exposes different element hierarchies that reflect their underlying Open XML structure.

PowerPoint (PPTX) Element Paths

PowerPoint documents organize content under slides, which may contain groups, shapes, pictures, charts, and tables. The examples/ppt/textboxes/textboxes-advanced.md file demonstrates that groups create nested contexts requiring full path chains:


# Address a shape inside a named group

officecli set "$FILE" "/slide[1]/group[@name=G]/shape[1]" --prop text="Nested"

# Address a picture by position on a specific slide

officecli set "$FILE" "/slide[2]/picture[3]" --prop fill=red

Excel (XLSX) Sheet Navigation

Excel addressing treats sheet names as direct children of the root. Tables, charts, sparklines, and cells are then addressed under their respective sheets. As shown in examples/excel/sparklines.md, sheet names act as the primary branch point:


# Reference a table by name within a specific sheet

officecli set "$FILE" "/Sheet1/table[@name=Sales]/cell[2,3]" --prop value=12345

# Address a sparkline collection

officecli get "$FILE" "/Sheet1/sparkline[1]"

Word (DOCX) Body Elements

Word documents centralize content under the /body path. Paragraphs, text boxes, tables, and charts appear as siblings under this container, as documented in examples/word/textbox.md:


# Modify the third text box in the document body

officecli set "$FILE" "/body/textbox[3]" --prop text="Introduction"

# Address a table cell within the body

officecli set "$FILE" "/body/table[1]/cell[1,1]" --prop text="Header"

Practical Implementation Examples

The following commands demonstrate real-world usage patterns from the repository examples. Replace $FILE with your target document path.


# 1. Create a shape with stable addressing, then update it

officecli add "$FILE" "/slide[1]" --type shape --prop name=Logo --prop preset=ellipse
officecli set "$FILE" "/slide[1]/shape[@name=Logo]" --prop fill=red

# 2. Reorder elements using positional addressing

officecli move "$FILE" "/slide[1]/shape[5]" --to "/slide[1]/shape[2]"

# 3. Remove an element by name (works across formats)

officecli remove "$FILE" "/slide[2]/comment[@name=ReviewerNote]"

# 4. Update nested table content in Excel

officecli set "$FILE" "/Sheet1/table[@name=Quarterly]/row[2]/cell[3]" --prop value=5000

Parser Architecture and Limitations

As implemented in iOfficeAI/OfficeCLI, the addressing parser treats paths as flat token lists rather than building a full DOM or XPath engine. This design choice eliminates namespace handling and complex predicate evaluation, ensuring sub-millisecond parsing performance even for deeply nested paths like /slide[2]/group[@name=G]/shape[1].

The README.md (lines 412-414) confirms that every element maintains a stable path, but warns that positional indexes are volatile while name-based attributes persist across document edits. Read-only containers such as presentation or workbook exist at the root level and cannot be addressed directly—only their children are mutable.

Summary

  • OfficeCLI path-based addressing syntax uses slash-delimited strings starting with / to navigate Office document hierarchies.
  • Positional indexes [N] provide quick access but break when document structure changes, while attribute selectors [@name=...] create stable, automation-friendly addresses.
  • The last() function dynamically targets the most recently added element of a type, ideal for post-creation workflows.
  • Format-specific roots vary: PowerPoint uses /slide, Excel uses /SheetName, and Word uses /body as primary containers.
  • The parser implements a flat tokenization system without full XPath complexity, ensuring reliable command-line performance.

Frequently Asked Questions

What is the difference between positional indexes and name-based selectors in OfficeCLI?

Positional indexes like [3] select the third occurrence of an element type in document order, but they shift when you add or remove elements. Name-based selectors like [@name=Logo] target specific elements by their persistent name attribute, creating stable addresses that survive structural changes. The examples/ppt/textboxes/textboxes-advanced.md file recommends using name attributes for all automation scripts.

Can I use full XPath expressions or wildcards in OfficeCLI paths?

No. According to the source implementation, OfficeCLI uses a simplified tokenizer that does not support XPath axes, wildcards, or complex predicates. You can only use element names, 1-based numeric indexes, [@name=...]/[@id=...] attribute filters, and the last() function. There is no namespace handling or descendant-or-self axis support.

How do I address elements in Excel worksheets versus PowerPoint slides?

Excel addresses sheets by their display name directly under root (e.g., /Sheet1), while PowerPoint uses the generic /slide[N] notation. Under Excel sheets, you address tables, charts, and sparklines by type, whereas PowerPoint requires navigating through group elements for nested content. The examples/excel/sparklines.md and skills/officecli-pptx/SKILL.md files provide format-specific guidance.

What happens if I use last() on an element type that doesn't exist?

The last() function evaluates to the highest current index of that element type. If no elements of the specified type exist, the path is invalid and the command will return an error indicating the address cannot be resolved. Always ensure at least one element exists before using last(), or use positional addressing for initial element creation.

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 →