How to Use CSS‑Like Query Selectors with Boolean Conditions in OfficeCLI

OfficeCLI supports a CSS‑inspired selector syntax with Boolean AND/OR logic to target specific elements across Word, Excel, and PowerPoint documents from the command line.

The OfficeCLI open‑source project provides a powerful query language for addressing document elements using familiar CSS patterns. According to the iOfficeAI/OfficeCLI source code, the selector engine tokenizes strings, parses attribute conditions with Boolean operators, and matches pseudo‑selectors—all implemented in the WordHandler.Selector.cs parser and invoked through ResidentServer.cs.

Understanding the Selector Grammar

The selector language in OfficeCLI follows a predictable pipeline defined in WordHandler.Selector.cs. Mastering these four stages lets you construct precise queries without trial and error.

Tokenization and Child Combinators

The raw selector string is first split on the child combinator > while respecting bracket boundaries. This happens in the SplitChildCombinator method (lines 31‑55 of WordHandler.Selector.cs).


# Descend from table → row → cell

officecli query --selector 'table > row[Score>80] > cell[Column="Total"]'

Each > introduces a new level in the document hierarchy, identical to CSS descendant navigation.

Element Names and Attribute Filters

After tokenization, ParseSingleSelector (lines 63‑84) extracts:

  1. The element name (e.g., row, p, cell)
  2. Attribute filters inside [ … ] brackets

# Element-only selector

officecli query --selector 'row'

# Element with attribute condition

officecli query --selector 'row[Score>80]'

Boolean Conditions in Attribute Selectors

OfficeCLI implements two explicit Boolean operators for combining conditions: AND (comma) and OR (pipe).

AND Logic with Commas

Multiple attribute clauses within the same bracket pair are evaluated as logical AND. The AttributeFilter.FilterSelector method (invoked from ResidentServer.cs lines 2078‑2088) processes each condition sequentially.


# Both conditions must match: Score > 80 AND Status equals "Approved"

officecli query --selector 'row[Score>80,Status="Approved"]'

OR Logic with the Pipe Operator

The pipe character | creates alternative matches. Internally, the engine splits these into separate AttributeFilter evaluations and merges results.


# Either condition matches: Dept is "HR" OR "Finance"

officecli query --selector 'row[Dept="HR"|Dept="Finance"]'

Supported Comparison Operators

Operator Meaning Example
= Equals Name="Budget"
!= Not equals Status!="Draft"
< Less than Score<100
<= Less than or equal Score<=100
> Greater than Score>80
>= Greater than or equal Score>=80

These operators are validated during parsing; malformed selectors trigger errors from ResidentServer.cs line 2078.

Pseudo‑Selectors for Content Matching

The ParseSingleSelector method (lines 106‑122) recognizes three CSS‑style pseudo‑selectors stored in the SelectorPart struct.

:contains("text")

Match elements containing specific text content.


# Find paragraphs containing "budget"

officecli query --selector 'p:contains("budget")'

:empty

Select elements with no content.


# Find empty table cells

officecli query --selector 'cell:empty'

:no-alt

Target images or objects lacking alternative text descriptions.

Complete Query Examples

Combine all syntax elements for production workflows:


# Numeric threshold with string equality (AND)

officecli query --selector 'row[Score>80,Active=true]'

# Cross-department search with OR logic

officecli query --selector 'row[Dept="HR"|Dept="Finance"|Dept="IT"]'

# Hierarchical navigation with conditions

officecli query --selector 'table > row[Score>80] > cell:empty'

# Content search within qualified elements

officecli query --selector 'table > row[Approved=true] > p:contains("signed")'

Error Handling and Debugging

Empty selectors throw immediate validation errors with a ready‑to‑copy correction example:

{"command":"query","selector":"row[Score>80]"}

When parsing fails during streaming operations, the try…catch block in watch-sse-core.js (line 330) silently skips malformed selectors. Enable verbose output to surface these issues:

officecli query --selector 'row[Score>80]' --verbose

Key Implementation Files

File Responsibility Key Methods
WordHandler.Selector.cs Selector grammar parsing SplitChildCombinator, ParseSingleSelector, MatchesParagraphAttrs, MatchesRunSelector
ResidentServer.cs Request routing and filter invocation AttributeFilter.FilterSelector call at line 2078
watch-sse-core.js Client‑side error suppression Exception handling at line 330

These files implement the complete CSS‑like selector engine that powers OfficeCLI's document querying capabilities.

Summary

  • Element selection uses familiar names (row, p, cell, table) parsed by ParseSingleSelector in WordHandler.Selector.cs
  • Boolean AND combines conditions with commas inside brackets: [Score>80,Status="Approved"]
  • Boolean OR uses the pipe operator: [Dept="HR"|Dept="Finance"]
  • Comparison operators include =, !=, <, <=, >, >= evaluated by AttributeFilter.FilterSelector
  • Pseudo‑selectors :contains(), :empty, and :no-alt extend matching to content and metadata
  • Child combinators (>) enable hierarchical navigation through document structures

Frequently Asked Questions

What happens if I use an invalid selector string?

OfficeCLI validates selectors early in ResidentServer.cs. An empty or malformed selector throws an error with a JSON example showing correct syntax. During streaming operations, watch-sse-core.js catches parsing exceptions and silently skips offending elements unless --verbose is enabled.

Can I mix AND and OR conditions in one selector?

Yes. You can chain multiple bracket blocks or use the pipe operator inside brackets. For complex logic, prefer explicit grouping: row[Dept="HR"|Dept="Finance"][Active=true] selects active rows from either department.

Do pseudo‑selectors work with all document types?

The WordHandler.Selector.cs implementation provides :contains("text"), :empty, and :no-alt for Word documents. Analogous parsers for Excel and PowerPoint implement equivalent pseudo‑selectors appropriate to those formats.

Is the selector syntax case‑sensitive?

Element names and attribute keys follow the document model conventions. String comparisons in attribute filters respect the case of the stored values—use consistent casing in your selectors or combine multiple OR conditions to match variations.

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 →