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 type –
shape,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:
- Word –
WordHandler.Query.csmatches<w:p>,<w:r>,<w:tbl>nodes - Excel –
ExcelHandler.csworks on<c>cells and named ranges - PowerPoint –
PowerPointHandler.Query.cstargets<p:sp>,<p:pic>,<p:graphicFrame>elements
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:
ParseSelector()– convert selector string toSelectorParttreeMatchesSelector()– evaluate against native document model- Registration in
ResidentServerhandler 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
queryprovides 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 throughAttributeFilter.cs - Results return as standardized JSON suitable for piping to
jqor 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →