How to Use CSS-Style Selectors with OfficeCLI's `query` Command

OfficeCLI's query command implements a universal CSS-style selector engine that works across all supported document types (Word .docx, Excel .xlsx, PowerPoint .pptx) through a consistent syntax for element selection, attribute filtering, and text matching.

The query sub-command is implemented in CommandBuilder.GetQuery.cs and provides read-only access to document structures using familiar CSS-style selector patterns. This article explains the selector syntax, execution flow, and practical examples for each Office format.

Selector Syntax Overview

OfficeCLI selectors support three core components that mirror CSS:

  • Element typeshape, paragraph, cell, image, picture, table, etc.
  • Attribute filters[fill=1E2761], [width>=10cm], [style=Heading1]
  • Pseudo-selectors:contains("text"), :empty, :no-alt, :has(formula), :nth-child(), :first, :last

Combine these for precise targeting: table>row[height>2cm]:first or shape[fill=1E2761]:contains("Revenue").

How the Query Engine Works

The execution flow involves four distinct layers, each implemented in specific source files.

1. Parsing the Selector String

The raw selector is parsed into a SelectorPart record defined in WordHandler.Selector.cs. This parser is shared across document types and captures:

  • Element name (shape, paragraph, cell)
  • Attribute filter dictionary
  • Optional :contains() text predicate
  • Optional child/descendant selectors

2. Attribute Evaluation

AttributeFilter.FilterSelector in Core/AttributeFilter.cs implements the comparison engine. It supports:

Operator Meaning Example
= exact match [fill=1E2761]
!= not equal [style!=Normal]
~= whitespace-separated list contains [class~=highlight]
>=, <= numeric comparison [width>=10cm]
[attr] existence check [alt]

This layer also handles pseudo-selectors like :empty and :no-alt.

3. Document-Specific Dispatch

ResidentServer.cs routes filtered selectors to format-specific handlers:

4. JSON Result Shaping

Results are wrapped in a uniform envelope:

{
  "data": {
    "results": [
      {
        "path": "/slide[3]/shape[2]",
        "format": { "id":"2","fill":"1E2761","textColor":"000000" },
        "name": "Revenue"
      }
    ]
  }
}

The complete schema is documented in each skill's SKILL.md file (e.g., skills/officecli-pptx/SKILL.md).

Practical Examples by Format

Word Documents (.docx)


# Find all level-1 headings

officecli query "$FILE" 'paragraph[style=Heading1]' --json

# Locate images missing alt-text for accessibility audits

officecli query "$FILE" 'image:no-alt' --json

# Find tables with specific styling

officecli query "$FILE" 'table[style=TableGrid]>row:first' --json

Excel Spreadsheets (.xlsx)


# List every formula cell

officecli query "$FILE" 'cell:has(formula)' --json

# Detect broken references

officecli query "$FILE" 'cell:contains("#REF!")' --json

# Filter by numeric value threshold

officecli query "$FILE" 'cell[value>=10000]' --json

PowerPoint Presentations (.pptx)


# Search shapes containing "Revenue"

officecli query "$FILE" 'shape:contains("Revenue")' --json

# Find pictures without alt text

officecli query "$FILE" 'picture:no-alt' --json

# Filter shapes by exact fill color (hex)

officecli query "$FILE" 'shape[fill=1E2761]' --json

# Combine conditions: colored shapes with specific text

officecli query "$FILE" 'shape[fill=1E2761]:contains("Q3")' --json

Post-Processing with jq

Pipe JSON output to jq for further analysis:


# Count matching results

officecli query "$FILE" 'shape:contains("Revenue")' --json |
  jq '.data.results | length'

# Extract first shape's ID for downstream automation

officecli query "$FILE" 'shape[fill=1E2761]' --json |
  jq -r '.data.results[0].format.id'

# Get all unique fill colors used

officecli query "$FILE" 'shape' --json |
  jq '[.data.results[].format.fill] | unique'

Key Source Files

File Responsibility
src/officecli/CommandBuilder.GetQuery.cs CLI argument parsing, query command entry point
src/officecli/Core/AttributeFilter.cs Attribute comparison engine, pseudo-selector implementation
src/officecli/Handlers/Word/WordHandler.Selector.cs Shared selector grammar parser
src/officecli/Handlers/Word/WordHandler.Query.cs Word-specific DOM traversal
src/officecli/Handlers/PowerPoint/PowerPointHandler.Query.cs PPTX shape/picture/chart queries
src/officecli/Handlers/Excel/ExcelHandler.cs Cell and range selection logic
src/officecli/ResidentServer.cs Handler dispatch and JSON result formatting

Extensibility Design

New document types integrate by implementing:

  1. ParseSelector() – convert selector string to SelectorPart tree
  2. MatchesSelector() – evaluate against native document model
  3. Registration in ResidentServer handler dispatch table

This architecture keeps the CSS-style selector language consistent across all Office formats while allowing each handler to expose format-specific attributes.

Summary

  • OfficeCLI query provides unified CSS-style selection across Word, Excel, and PowerPoint
  • Selectors combine element types, attribute filters, and pseudo-selectors in standard CSS syntax
  • Core parsing lives in WordHandler.Selector.cs; evaluation runs through AttributeFilter.cs
  • Results return as standardized JSON suitable for piping to jq or other tools
  • The handler-based architecture enables consistent syntax with format-specific capabilities

Frequently Asked Questions

What file formats support CSS-style selectors in OfficeCLI?

OfficeCLI's query command supports Word .docx, Excel .xlsx, and PowerPoint .pptx through dedicated handlers. Each format exposes its own element types (paragraph vs cell vs shape) but uses identical selector syntax. The handlers map generic selectors onto format-specific Open XML node types.

How do I filter elements by text content?

Use the :contains("text") pseudo-selector. For example, shape:contains("Revenue") matches any shape containing that substring. For Excel formulas, use :has(formula) to detect formula cells. Text matching is case-sensitive and supports Unicode content.

Can I combine multiple attribute conditions?

Yes. Chain filters without spaces: shape[fill=1E2761][width>=10cm]:contains("Q3"). The parser treats this as logical AND. For OR conditions, run separate queries and merge results with jq, as the selector engine does not implement CSS comma syntax.

Where is the complete JSON output schema documented?

Each skill directory contains a SKILL.md file with the full schema. See skills/officecli-pptx/SKILL.md, skills/officecli-docx/SKILL.md, and skills/officecli-xlsx/SKILL.md in the repository. All schemas share the top-level structure {"data":{"results":[...]}} with format-specific fields inside the format object.

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 →