How to Use OfficeCLI Raw XML Commands for Direct XPath Manipulation

OfficeCLI exposes a low-level interface via raw and raw-set commands that let you read, edit, and validate OpenXML parts using standard XPath expressions, bypassing the high-level object model for precise control over document structure.

OfficeCLI is an open-source command-line tool for automating Microsoft Office documents hosted at iOfficeAI/OfficeCLI. When you need to manipulate document elements that aren't exposed through standard high-level commands, the OfficeCLI raw XML commands for direct XPath manipulation provide direct access to the underlying OpenXML package parts, enabling surgical modifications to Word, Excel, and PowerPoint files.

Core Architecture of Raw XML Processing

The raw XML functionality centers on three components implemented in the source tree:

  • RawXmlHelper (src/officecli/Core/RawXmlHelper.cs): The central engine that loads XML parts, resolves namespaces, executes XPath queries against XDocument objects, and persists changes back to the package archive.

  • CommandBuilder.Raw (src/officecli/CommandBuilder.Raw.cs): Defines the CLI surface for the raw and raw-set sub-commands, parsing the required --xpath option and routing requests to the helper.

  • CLI Host (src/officecli/officecli.csproj): Orchestrates the workflow by opening the target document, streaming the selected part to RawXmlHelper, and rendering results or error diagnostics via OutputFormatter.

When you invoke a raw command, the tool opens the Office document (.docx, .xlsx, .pptx), locates the requested part using the internal path model, constructs an XmlNamespaceManager from the part's declarations, and executes the XPath against the DOM. For write operations, the modified XDocument is serialized back into the ZIP archive while preserving relationships and document structure.

Querying Document Structure with raw

The raw command performs read-only XPath evaluation against a specific document part. Use this to inspect elements, extract attribute values, or verify document structure before modification.

The XPath implementation uses 1-based indexing that mirrors the Office CLI path model. For example, /body/p[2] selects the second paragraph, consistent with standard XML semantics.

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

This query targets the first table in the document body, selects the second row and third cell, and returns the paragraph element(s) within that cell. The command outputs the raw XML of matched nodes, making it useful for discovering the exact structure before writing modifications.

To consume results programmatically, append the --json flag to receive a structured array of matches:

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

This returns JSON containing the relationship IDs of all images on slide 2, enabling downstream automation scripts to process embedded media.

Modifying Content Using raw-set

The raw-set command follows the same resolution logic as raw but writes the transformed XML back to the document. This enables three primary operations: attribute modification, element insertion, and node deletion.

Updating Attributes

Target an attribute node with @ syntax and supply the replacement XML fragment via --value:

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

This locates the width attribute of the first table's properties and updates it to 5000 twips.

Inserting Elements

When the XPath resolves to a container node, the supplied value is appended as a child:

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>"

This appends a new row to the end of the first table by targeting w:tr[last()] and injecting a complete table row fragment.

Deleting Nodes

Pass an empty string to --value to remove all nodes matching the XPath:

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

This removes all empty paragraphs (those lacking text runs) from the document body.

Namespace Handling and Error Diagnostics

OfficeCLI eliminates manual namespace management by automatically registering prefixes from the target part's declarations. You can use standard Office OpenXML prefixes—w: for WordprocessingML, a: for DrawingML, r: for relationships—without declaring them in your XPath expression.

The helper supports advanced XPath features including:

  • Wildcard selectors: * matches any element
  • Attribute predicates: [@val='true'] filters by attribute value
  • Position functions: [last()] selects the final node in a set

Error handling is implemented in src/officecli/Core/OutputFormatter.cs, which surfaces actionable messages such as "XPath matched no elements" or "Expression must evaluate to a node-set" when queries fail validation. This prevents silent failures and helps debug malformed expressions.

Internal handlers like WordHandler.Navigation.cs leverage these same raw commands for complex navigation scenarios, demonstrating that the XPath layer serves as the foundation for higher-level operations within the codebase.

Summary

  • RawXmlHelper.cs provides the core engine for loading, querying, and saving XML parts via XPath.
  • The raw command enables read-only inspection of document structure using standard XPath 1.0 syntax.
  • The raw-set command writes modifications back to the package, supporting attribute updates, element insertion, and node deletion.
  • Automatic namespace resolution allows use of standard Office prefixes (w:, a:, r:) without manual declaration.
  • 1-based indexing in XPath predicates aligns with the Office CLI path model and standard XML conventions.

Frequently Asked Questions

What is the difference between raw and raw-set commands?

The raw command performs read-only queries against document parts and returns the matching XML nodes to stdout. The raw-set command performs the same query but expects a --value parameter; it replaces the matched nodes with the supplied XML fragment and writes the modified document back to the original file. According to the implementation in CommandBuilder.Raw.cs, both commands share the same XPath resolution logic but diverge at the persistence layer handled by RawXmlHelper.

How does OfficeCLI handle XML namespaces in XPath queries?

OfficeCLI automatically constructs an XmlNamespaceManager from the namespace declarations present in the target OpenXML part. This allows you to use shorthand prefixes like w:tbl (Word), a:blip (DrawingML), or r:embed (Relationships) without manually mapping URIs. The resolution happens in RawXmlHelper.cs before the XPath is compiled, ensuring valid queries against namespaced elements.

Can I use OfficeCLI raw commands to delete elements from a document?

Yes. To delete nodes, use the raw-set command with an empty string for the --value parameter. For example, --xpath "//w:p[not(w:r)]" --value "" removes all empty paragraphs. The helper treats an empty value as a deletion instruction and removes the matched nodes from the XDocument before saving.

What happens if my XPath expression matches no elements?

If the XPath evaluates to an empty node-set, RawXmlHelper catches this condition and emits an error message through OutputFormatter.cs stating "XPath matched no elements." The command exits with a non-zero status, preventing accidental no-op modifications. Similarly, if your expression returns a scalar value instead of a node-set when a node is expected, you'll receive "Expression must evaluate to a node-set."

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 →